# with spaces.
INPUT = @top_srcdir@/src/lib \
+ @top_srcdir@/src/bindings \
@srcdir@/main.dox \
@srcdir@/pkgconfig.dox \
@srcdir@/eina_examples.dox \
FILE_PATTERNS = *.c \
*.h \
- *.x
+ *.x \
+ *.hh
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
#ifndef EINA_HH_
#define EINA_HH_
+/**
+ * @file
+ * @brief Eina C++
+ */
+
#include <eina_iterator.hh>
#include <eina_ptrarray.hh>
#include <eina_ptrlist.hh>
#include <eina_optional.hh>
#include <eina_integer_sequence.hh>
+/**
+ * @defgroup Eina_Cxx Eina C++
+ *
+ * @defgroup Eina_Cxx_Data_Types_Group Data Types
+ * @ingroup Eina_Cxx
+ *
+ * @defgroup Eina_Cxx_Content_Access_Group Content Access
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * @defgroup Eina_Cxx_Containers_Group Containers
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * @defgroup Eina_Cxx_Tools_Group Tools
+ * @ingroup Eina_Cxx
+ *
+ */
+
namespace efl { namespace eina {
+/**
+ * @addtogroup Eina_Cxx
+ *
+ * @{
+ */
+
+/**
+ * @brief Initialize the Eina library.
+ *
+ * Initialize all the Eina modules upon construction and finalize them
+ * upon destruction, using the RAII programming idiom.
+ */
struct eina_init
{
eina_init()
}
};
+/**
+ * @brief Initialize the mutexes of the Eina library.
+ *
+ * Set up all the mutexes in all Eina modules upon construction and
+ * shut them down upon destruction, using the RAII programming idiom.
+ */
struct eina_threads_init
{
eina_threads_init()
}
};
+/**
+ * @}
+ */
+
} }
#endif
#include <cstdlib>
#include <cassert>
+/**
+ * @addtogroup Eina_Cxx_Content_Access_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Accessor_Group Accessor
+ * @ingroup Eina_Cxx_Content_Access_Group
+ *
+ * @brief These classes manage accessor on containers.
+ *
+ * These classes allow to access elements of a container in a
+ * generic way, without knowing which container is used (like
+ * iterators in the C++ STL). Accessors allows random access (that is, any
+ * element in the container). For sequential access, see
+ * @ref Eina_Cxx_Iterator_Group.
+ *
+ * @{
+ */
+
+/**
+ * Wraps an native Eina_Accessor and provide random access to data structures.
+ */
template <typename T>
struct accessor
{
- typedef unsigned int key_type;
- typedef T mapped_type;
- typedef T value_type;
- typedef std::size_t size_type;
+ typedef unsigned int key_type; /**< Type for accessor key. */
+ typedef T mapped_type; /**< Type for accessor mapped elements. */
+ typedef T value_type; /**< Type for accessor elements. Same as @ref mapped_type. */
+ typedef std::size_t size_type; /**< Type for size information used in the accessor. */
+ /**
+ * @brief Default constructor. Creates an empty accessor.
+ */
accessor() : _impl(0) {}
+
+ /**
+ * @brief Create an accessor object that wraps the given Eina accessor.
+ * @param impl Native @c Eina_Accessor to be wrapped.
+ *
+ * This constructor creates an accessor object that wraps the given
+ * Eina_Accessor and provides access to the data pointed by it.
+ *
+ * @warning It is important to note that the created accessor object
+ * gains ownership of the given handle, deallocating it at destruction
+ * time.
+ */
explicit accessor(Eina_Accessor* impl)
: _impl(impl)
{
assert(_impl != 0);
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given accessor object.
+ * @param other Other accessor object.
+ *
+ * This constructor clones the internal @c Eina_Accessor of the given
+ * accessor object, so that the newly created object can be used
+ * freely.
+ */
accessor(accessor<T> const& other)
: _impl(eina_accessor_clone(other._impl))
{}
+
+ /**
+ * @brief Assignment Operator. Replace the current content.
+ * @param other Other accessor object.
+ * @throw <tt>eina::system_error</tt> if the Eina accessor could not be cloned.
+ *
+ * This operator replaces the current native Eina accessor by a copy
+ * of the native accessor inside the given object.
+ */
accessor<T>& operator=(accessor<T> const& other)
{
eina_accessor_free(_impl);
throw eina::system_error(efl::eina::get_error_code(), "Error cloning accessor");
return *this;
}
+
+ /**
+ * @brief Destructor. Free the internal @c Eina_Acessor.
+ */
~accessor()
{
eina_accessor_free(_impl);
}
-
+
+ /**
+ * @brief Retrieve the data of the accessor at a given position.
+ * @param i The position of the element.
+ * @return Constant reference to the retrieved data.
+ * @throw <tt>eina::system_error</tt> if the given element could not be retrieved.
+ *
+ * This operator retrieves a constant reference to the element at the
+ * given position. If the element could not be retrieved an
+ * <tt>eina::system_error</tt> is thrown.
+ */
mapped_type& operator[](size_type i) const
{
assert(_impl != 0);
return *static_cast<mapped_type*>(p);
}
+ /**
+ * @brief Get the handle for the wrapped @c Eina_Accessor.
+ * @return Internal handle for the native Eina accessor.
+ *
+ * This member function returns the native @c Eina_Accessor handle
+ * that is wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
Eina_Accessor* native_handle() const;
+ /**
+ * @brief Swap content between both objects.
+ * @param other Other accessor object.
+ *
+ * This member function swaps the internal @c Eina_Acessor with the
+ * given accessor object.
+ */
void swap(accessor<T>& other)
{
std::swap(_impl, other._impl);
}
+ /**
+ * @brief Cast to @c boolean based on the wrapped @c Eina_Accessor.
+ * @return @c true if the wrapped handle is not @c NULL, @c false otherwise.
+ *
+ * Boolean typecast overload for easy validation of the accessor
+ * object. Returns @c false if it does not have an internal
+ * @c Eina_Accessor, i.e. if the current handle is not @c NULL.
+ */
explicit operator bool() const
{
return native_handle() ? &accessor<T>::native_handle : 0 ;
}
private:
+
+ /**
+ * @internal
+ * Member variable for storing the native Eina_Accessor pointer.
+ */
Eina_Accessor* _impl;
};
+/**
+ * @brief Swap the contents of the two accessor objects.
+ * @param lhs First accessor object.
+ * @param rhs Second accessor object.
+ */
template <typename U>
void swap(accessor<U>& lhs, accessor<U>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eina_Cxx_Accessor_Iterator_Group Accessor Iterator
+ * @ingroup Eina_Cxx_Content_Access_Group
+ *
+ * @{
+ */
+
+/**
+ * Random access iterator for <tt>eina::accessor</tt>.
+ */
template <typename T>
struct accessor_iterator
{
- typedef T value_type;
- typedef value_type* pointer;
- typedef value_type& reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type; /**< Type of the elements. */
+ typedef value_type* pointer; /**< Pointer to element type. */
+ typedef value_type& reference; /**< Reference to element type. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two @ref accessor_iterators */
+ typedef std::random_access_iterator_tag iterator_category; /**< Defines the iterator as being a random access iterator. */
+
+ /**
+ * @brief Creates an @c accessor_iterator to the given <tt>eina::accessor</tt>.
+ * @param a <tt>eina::accessor</tt> object.
+ * @param pos Initial position of the iterator (Default = @c 0).
+ *
+ * This constructor creates an @c accessor_iterator for the given
+ * <tt>eina::accessor</tt> object. The position initially pointed by
+ * the iterator can be supplied via the @p pos argument, by default
+ * it is the first position (index @c 0).
+ */
accessor_iterator(accessor<T> const& a, unsigned int pos = 0u)
: _accessor(a), _index(pos)
{}
+ /**
+ * @brief Move the iterator forward by @p i positions.
+ * @param i Number of positions to move.
+ * @return The @c accessor_iterator itself.
+ */
accessor_iterator<T>& operator+=(difference_type i)
{
_index += i;
return *this;
}
+
+ /**
+ * @brief Move the iterator back by @p i positions.
+ * @param i Number of positions to move.
+ * @return The @c accessor_iterator itself.
+ */
accessor_iterator<T>& operator-=(difference_type i)
{
_index -= i;
return *this;
}
+
+ /**
+ * @brief Get the element @p i positions away from the current element.
+ * @param i Position relative to the current element.
+ * @return Reference to the element @p i positions away from the
+ * element currently pointed by the @c accessor_iterator.
+ */
value_type& operator[](difference_type i)
{
return _accessor[_index + i];
}
+
+ /**
+ * @brief Move the iterator to the next position.
+ * @return The @c accessor_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.
+ */
accessor_iterator<T>& operator++()
{
++_index;
return *this;
}
+
+ /**
+ * @brief Move the iterator to the previous position.
+ * @return The @c accessor_iterator itself.
+ *
+ * This operator decrements the iterator, making it point to the
+ * position right before the current one.
+ * At the end, it returns a reference to itself.
+ */
accessor_iterator<T>& operator--()
{
--_index;
return *this;
}
+
+ /**
+ * @brief Move the iterator to the next position.
+ * @return A copy of the @c accessor_iterator before the change.
+ *
+ * This operator increments the iterator, making it point to the
+ * position right after the current one.
+ * At the end, it returns a copy of the @c accessor_iterator before
+ * the change.
+ */
accessor_iterator<T>& operator++(int)
{
accessor_iterator<T> tmp(*this);
++*this;
return tmp;
}
+
+ /**
+ * @brief Move the iterator to the previous position.
+ * @return A copy of the @c accessor_iterator before the change.
+ *
+ * This operator decrements the iterator, making it point to the
+ * position right before the current one.
+ * At the end, it returns a copy of the @c accessor_iterator before
+ * the change.
+ */
accessor_iterator<T>& operator--(int)
{
accessor_iterator<T> tmp(*this);
--*this;
return tmp;
}
+
+ /**
+ * @brief Get a reference to the element currently pointed by the @c accessor_iterator.
+ * @return Reference to the current element.
+ */
value_type& operator*() const
{
return _accessor[_index];
}
+
+ /**
+ * @brief Return a pointer to the current element, which member will be accessed.
+ * @return Pointer to the element currently pointed by the @c accessor_iterator.
+ */
pointer operator->() const
{
return &**this;
}
+
+ /**
+ * @brief Swap content with the given @c accessor_iterator.
+ * @param other Another @c accessor_iterator of the same type.
+ */
void swap(accessor_iterator<T>& other)
{
std::swap(_index, other._index);
std::swap(_accessor, other._accessor);
}
+
private:
- accessor<T> _accessor;
- unsigned int _index;
+ accessor<T> _accessor; /**< @internal */
+ unsigned int _index; /**< @internal */
+ /**
+ * @brief Check if @p lhs and @p rhs point to the same position.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if both @p lhs and @p rhs point to the same position.
+ */
template <typename U>
friend bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
return lhs._index == rhs._index;
}
+ /**
+ * @brief Get the distance between two <tt>accessor_iterator</tt>s.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return The number of elements between @p lhs and @p rhs.
+ */
template <typename U>
friend typename accessor_iterator<U>::difference_type
operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
return lhs._index - rhs._index;
}
+ /**
+ * @brief Get an @c accessor_iterator moved @p rhs positions forward.
+ * @param lhs @c accessor_iterator object.
+ * @param rhs Number of positions relative to the current element.
+ * @return Copy of @p lhs moved @p rhs positions forward.
+ */
template <typename U>
friend
accessor_iterator<U> operator+(accessor_iterator<U> lhs
return lhs;
}
+ /**
+ * @brief Get an @c accessor_iterator moved @p lhs positions forward.
+ * @param lhs Number of positions relative to the current element.
+ * @param rhs @c accessor_iterator object.
+ * @return Copy of @p rhs moved @p lhs positions forward.
+ */
template <typename U>
friend
accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
return rhs + lhs;
}
+ /**
+ * @brief Check if @p lhs points to a position before the position pointed by @p rhs.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if @p lhs points to a position before the position
+ * pointed by @p rhs, @c false otherwise.
+ */
template <typename U>
friend bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
return lhs._index < rhs._index;
}
+ /**
+ * @brief Check if the position pointed by @p lhs is the same or is before the one pointed by @p rhs.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if the position pointed by @p lhs is the same or is
+ * before the position pointed by @p rhs, @c false otherwise.
+ */
template <typename U>
friend bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
}
};
+/**
+ * @brief Check if the position pointed by @p lhs is the same or is after the one pointed by @p rhs.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if the position pointed by @p lhs is the same or is
+ * after the position pointed by @p rhs, @c false otherwise.
+ */
template <typename U>
bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
return !(lhs < rhs);
}
+/**
+ * @brief Check if @p lhs points to a position after the position pointed by @p rhs.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if @p lhs points to a position after the position
+ * pointed by @p rhs, @c false otherwise.
+ */
template <typename U>
bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
return !(lhs <= rhs);
}
+/**
+ * @brief Check if @p lhs and @p rhs point to different positions.
+ * @param lhs @c accessor_iterator at the left side of the expression.
+ * @param rhs @c accessor_iterator at the right side of the expression.
+ * @return @c true if @p lhs and @p rhs point to different positions.
+ */
template <typename U>
bool operator!=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Swap content between two <tt>accessor_iterator</tt>s.
+ * @param lhs First @c accessor_iterator.
+ * @param rhs Second @c accessor_iterator.
+ */
template <typename U>
void swap(accessor_iterator<U>& lhs, accessor_iterator<U>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <cstdlib>
#include <type_traits>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Clone_Allocators_Group Clone Allocators
+ * @ingroup Eina_Cxx_Containers_Group
+ *
+ * Clone allocators is a formalized way to pointer containers control
+ * the memory of the stored objects, allowing users to apply custom
+ * allocators/deallocators for the cloned objects.
+ *
+ * @{
+ */
+
+/**
+ * This allocator creates copies of objects on the heap, calling their
+ * copy constructor to make then equivalent to the given reference.
+ *
+ * The created objects are released with the default delete.
+ */
struct heap_copy_allocator
{
template <typename T>
}
};
+/**
+ * This allocator allows users to create custom allocation schemes by
+ * overloading the <tt>new_clone(T const& v)</tt> and
+ * <tt>delete_clone(T* p)</tt> functions.
+ */
struct heap_clone_allocator
{
template <typename T>
}
};
+/**
+ * This allocator does not allocate or deallocate anything. It simple
+ * gets non-const-qualified pointers for objects, which allow
+ * containers to hold elements without having ownership on them.
+ *
+ * It is commonly used to create a pointer container that is a view into
+ * another existing container.
+ */
struct view_clone_allocator
{
template <typename T>
}
};
+/**
+ * This allocator does not define an @c allocate_clone member function,
+ * so it should be used to disable operations that require elements to
+ * be cloned.
+ */
struct heap_no_copy_allocator
{
template <typename T>
delete p;
#endif
}
-};
+};
+/**
+ * Manages allocation and deallocation of memory using the function
+ * @c malloc and @c free. This allocator does not calls constructors,
+ * the content of the newly allocated objects are assigned using
+ * @c memcpy, so it is likely only plausible with types that have
+ * <em>standard-layout</em>.
+ */
struct malloc_clone_allocator
{
template <typename T>
}
};
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <system_error>
+/**
+ * @addtogroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Error_Group Error Handling
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @brief Functions for handling Eina errors.
+ *
+ * Integrates the Eina errors with the standard error representation
+ * defined in the @c system_error library.
+ *
+ * @{
+ */
+
+/** <tt>std::errc</tt> for Eina errors. */
using std::errc;
+
+/** <tt>std::system_error</tt> for Eina errors. */
using std::system_error;
+
+/** <tt>std::error_code</tt> for Eina errors. */
using std::error_code;
+
+/** <tt>std::error_condition</tt> for Eina errors. */
using std::error_condition;
+
+/** <tt>std::error_category</tt> for Eina errors. */
typedef std::error_category system_error_category;
+/**
+ * @brief Return a @c Eina_Error for an unknown error.
+ * @return @c Eina_Error indicating a unknown/external error condition.
+ *
+ * This function returns an @c Eina_Error indicating a unknown/external
+ * error condition. When first called, this function will register the
+ * said error within the other Eina errors, together with a error
+ * message.
+ */
inline Eina_Error unknown_error()
{
static Eina_Error error = eina_error_msg_static_register("Error from C++ from another value category error");
return error;
}
+/**
+ * @brief Gets a <tt>std::generic_category</tt> instance as a <tt>eina::system_error_category</tt>.
+ * @return a <tt>std::generic_category</tt> instance as a <tt>eina::system_error_category</tt>.
+ */
inline system_error_category const& get_generic_category()
{
return ::std::generic_category();
}
+
+/**
+ * @brief Gets a <tt>std::system_category</tt> instance as a <tt>eina::system_error_category</tt>.
+ * @return <tt>std::system_category</tt> instance as a <tt>eina::system_error_category</tt>.
+ */
inline system_error_category const& get_system_category()
{
return ::std::system_category();
}
+/**
+ * @brief Typesafe representation of an @c Eina_Error.
+ *
+ * Used for improved compatibility with @e system_error library.
+ */
enum error_type {};
+/**
+ * @brief Specialized error category for Eina errors.
+ */
struct error_category : system_error_category
{
+ /**
+ * @brief Name of the error category.
+ * @return String containing the word "eina"
+ */
const char* name() const throw()
{
return "eina";
}
+ /**
+ * @brief Check if the given error code is equivalent to the given error condition.
+ * @param code Integer representing the error code.
+ * @param condition <tt>eina::error_condition</tt> object.
+ * @return @c true if @c code is equivalent to @c condition.
+ */
bool equivalent(int code, eina::error_condition const& condition) const throw()
{
return code == condition.value();
}
+ /**
+ * @brief Check if the given error code is equivalent to the given error condition.
+ * @param code <tt>eina::error_code</tt> object.
+ * @param condition Integer representing the error condition.
+ * @return @c true if @c code is equivalent to @c condition.
+ */
bool equivalent(eina::error_code const& code, int condition) const throw()
{
return code.value() == condition;
}
+ /**
+ * @brief Get the message related with the given error condition.
+ * @param condition Eina error condition.
+ * @return String containing the message related with the given error condition.
+ *
+ * This member function returns the error message related with the
+ * given error condition code.
+ *
+ * @note When the given condition code is not registered within the
+ * Eina errors it will return a string indicating that an error
+ * message is not available.
+ */
std::string message(int condition) const
{
const char* e = ::eina_error_msg_get(condition);
}
};
+/**
+ * @brief Get a default <tt>eina::error_category</tt> object.
+ * @return Reference to a static instance of an <tt>eina::error_category</tt>.
+ */
inline eina::system_error_category& eina_error_category()
{
static error_category _error_category;
return _error_category;
}
+/**
+ * @brief Gets the error code for the last Eina error.
+ * @return <tt>eina::error_code</tt> for the last Eina error.
+ *
+ * This function gets the error code for the last Eina error and
+ * consumes it. The category of the returned <tt>eina::error_code</tt>
+ * is @c eina_error_category.
+ *
+ * @note If no errors have been occurred or if this functions have
+ * already been called after the last error occurrence a call to this
+ * function will return a default <tt>eina::error_code</tt> to indicates
+ * that there is no unconsumed error.
+ */
inline eina::error_code get_error_code()
{
Eina_Error error = eina_error_get();
return eina::error_code();
}
+/**
+ * @brief Sets an error code in the Eina library.
+ * @param e Error code. Should be an @c eina_error_category error.
+ *
+ * This function sets an error code in the Eina library. If the category
+ * of the given error code is not @c eina_error_category it will
+ * register an unknown error instead.
+ */
inline void set_error_code(eina::error_code const& e)
{
if(e.category() == eina_error_category())
eina_error_set(unknown_error());
}
+/**
+ * @brief Gets the error condition for the last Eina error.
+ * @return <tt>eina::error_condition</tt> for the last Eina error.
+ *
+ * This function works exactly like @ref get_error_code but returns an
+ * <tt>eina::error_condition</tt> object instead.
+ */
inline eina::error_condition get_error_condition()
{
Eina_Error error = eina_error_get();
return eina::error_condition();
}
+/**
+ * @brief Gets the enum value of the last Eina error.
+ * @return Value of the last Eina error as an @c error_type.
+ *
+ * This function returns the error code for the last Eina error.
+ *
+ * Differently from @ref get_error_code and @ref get_error_condition,
+ * this function does not consume the last error.
+ */
inline error_type get_error_code_enum()
{
return static_cast<error_type>( ::eina_error_get() );
}
+/**
+ * @brief Throw an exception if there is a error set in Eina library.
+ * @throw <tt>eina::system_error</tt> containing the error identifier.
+ *
+ * This function is meant to be used after executing a operation that
+ * may set an Eina error. If an error code has been set this function
+ * will throw an exception.
+ *
+ * The thrown exception holds an <tt>eina::error_code</tt> equivalent to
+ * the one returned by @ref get_error_code.
+ *
+ * Like the @ref get_error_code function, this one consumes the last
+ * error code.
+ */
inline void throw_on_error()
{
eina::error_code ec = get_error_code();
}
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @internal
+ * Template specialization for interoperability with the @e system_error
+ * standard library.
+ * @{
+ */
namespace std {
-
template <> struct is_error_condition_enum< ::efl::eina::error_type> : true_type {};
template <> struct is_error_code_enum< ::efl::eina::error_type> : true_type {};
-
}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
#endif
#include <cstring>
#include <cassert>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Inline_Array_Group Inline Array
+ * @ingroup Eina_Cxx_Containers_Group
+ *
+ * Inline array is a container that stores the data itself not pointers to data,
+ * this means there is no memory fragmentation, also for small data types(such
+ * as char, short, int, etc.) it's more memory efficient.
+ *
+ * @{
+ */
+
+/**
+ * @internal
+ * Access traits for eina::inarray.
+ */
struct _inarray_access_traits {
template <typename T>
struct const_iterator
{
- typedef T const* type;
+ typedef T const* type; /**< Type for constant iterator. */
};
template <typename T>
struct iterator
{
- typedef T* type;
+ typedef T* type; /**< Type for iterator. */
};
template <typename T>
struct const_native_handle
{
- typedef Eina_Inarray const* type;
+ typedef Eina_Inarray const* type; /**< Type for constant native @c Eina_Inarray handle. */
};
template <typename T>
struct native_handle
{
- typedef Eina_Inarray* type;
+ typedef Eina_Inarray* type; /**< Type for native @c Eina_Inarray handle. */
};
+ /**
+ * @brief Get a non-constant native @c Eina_Inarray handle from a constant one.
+ */
template <typename T>
static Eina_Inarray* native_handle_from_const(Eina_Inarray const* array)
{
return const_cast<Eina_Inarray*>(array);
}
+
+/**
+ * @brief Get a reference to the last element of the given @c Eina_Inarray.
+ */
template <typename T>
static T& back(Eina_Inarray* raw)
{
assert(!_inarray_access_traits::empty<T>(raw));
return *static_cast<T*>( ::eina_inarray_nth(raw, _inarray_access_traits::size<T>(raw)-1u));
}
+/**
+ * @brief Get a constant reference to the last element of the given @c Eina_Inarray.
+ *
+ * Version of @ref back(Eina_Inarray* raw) for const-qualified pointer
+ * to @c Eina_Inarray. Get a constant reference to the last element
+ * instead.
+ */
template <typename T>
static T const& back(Eina_Inarray const* raw)
{
return _inarray_access_traits::back<T>(const_cast<Eina_Inarray*>(raw));
}
+
+/**
+ * @brief Get a reference to the first element of the given @c Eina_Inarray.
+ */
template <typename T>
static T& front(Eina_Inarray* raw)
{
assert(!empty<T>(raw));
return *static_cast<T*>( ::eina_inarray_nth(raw, 0u));
}
+
+/**
+ * @brief Get a constant reference to the first element of the given @c Eina_Inarray.
+ *
+ * Version of @ref front(Eina_Inarray* raw) for const-qualified
+ * pointer to @c Eina_Inarray. Get a constant reference to the first
+ * element instead.
+ */
template <typename T>
static T const& front(Eina_Inarray const* raw)
{
return _inarray_access_traits::front<T>(const_cast<Eina_Inarray*>(raw));
}
+
+/**
+ * @brief Get an iterator to the begin of the memory block of the given @c Eina_Inarray.
+ */
template <typename T>
static T* begin(Eina_Inarray* raw)
{
return !raw->members ? 0 : static_cast<T*>( ::eina_inarray_nth(raw, 0u));
}
+
+/**
+ * @brief Get an iterator to the end of the memory block of the given @c Eina_Inarray.
+ */
template <typename T>
static T* end(Eina_Inarray* raw)
{
return !raw->members ? 0
: static_cast<T*>( ::eina_inarray_nth(raw, _inarray_access_traits::size<T>(raw) -1)) + 1;
}
+
+/**
+ * @brief Get a constant iterator to the begin of the memory block of the given @c Eina_Inarray.
+ *
+ * Version of @ref begin(Eina_Inarray* raw) for const-qualified
+ * @c Eina_Inarray handles. Returns a constant iterator instead.
+ */
template <typename T>
static T const* begin(Eina_Inarray const* raw)
{
return _inarray_access_traits::begin<T>(const_cast<Eina_Inarray*>(raw));
}
+
+
+/**
+ * @brief Get a constant iterator to the end of the memory block of the given @c Eina_Inarray.
+ *
+ * Version of @ref end(Eina_Inarray* raw) const-qualified
+ * @c Eina_Inarray. Returns a constant iterator instead.
+ */
template <typename T>
static T const* end(Eina_Inarray const* raw)
{
return _inarray_access_traits::end<T>(const_cast<Eina_Inarray*>(raw));
}
+
+/**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the given Eina_Inarray.
+ *
+ * Version of @ref rbegin(Eina_Inarray* raw) for const-qualified
+ * Eina_Inarray handles. Returns a constant reverse iterator instead.
+ */
template <typename T>
static std::reverse_iterator<T const*> rbegin(Eina_Inarray const* raw)
{
return std::reverse_iterator<T const*>(_inarray_access_traits::end<T>(raw));
}
+
+/**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the given Eina_Inarray.
+ *
+ * Version of @ref rend(Eina_Inarray* raw) to const-qualified
+ * Eina_Inarray handles. Returns a constant reverse iterator instead.
+ */
template <typename T>
static std::reverse_iterator<T const*> rend(Eina_Inarray const* raw)
{
return std::reverse_iterator<T const*>(_inarray_access_traits::begin<T>(raw));
}
+
+/**
+ * @brief Get a reverse iterator pointing to the reverse begin of the given @c Eina_Inarray.
+ */
template <typename T>
static std::reverse_iterator<T*> rbegin(Eina_Inarray* raw)
{
return std::reverse_iterator<T*>(_inarray_access_traits::end<T>(raw));
}
+
+/**
+ * @brief Get a reverse iterator pointing to the reverse end of the given @c Eina_Inarray.
+ */
template <typename T>
static std::reverse_iterator<T*> rend(Eina_Inarray* raw)
{
return std::reverse_iterator<T*>(_inarray_access_traits::begin<T>(raw));
}
+
+/**
+ * @brief Get a constant iterator to the begin of the memory block of the given @c Eina_Inarray.
+ *
+ * Works like @ref begin(Eina_Inarray const* raw) but is granted to
+ * return a constant iterator even for handles that are not
+ * const-qualified.
+ */
template <typename T>
static T const* cbegin(Eina_Inarray const* raw)
{
return _inarray_access_traits::begin<T>(raw);
}
+
+/**
+ * @brief Get a constant iterator to the end of the memory block of the given @c Eina_Inarray.
+ *
+ * Works like @ref end(Eina_Inarray const* raw) but is granted to
+ * return a constant iterator even for handles that are not
+ * const-qualified.
+ */
template <typename T>
static T const* cend(Eina_Inarray const* raw)
{
return _inarray_access_traits::end<T>(raw);
}
+
+/**
+ * @brief Get a constant reverse iterator to the end of the memory block of the given @c Eina_Inarray.
+ *
+ * Works like @ref rbegin(Eina_Inarray const* raw) but is granted to
+ * return a constant reverse iterator even for handles that are not
+ * const-qualified.
+ */
template <typename T>
static std::reverse_iterator<T const*> crbegin(Eina_Inarray const* raw)
{
return _inarray_access_traits::rbegin<T const*>(raw);
}
+
+/**
+ * @brief Get a constant reverse iterator to the begin of the memory block of the given @c Eina_Inarray.
+ *
+ * Works like @ref rend(Eina_Inarray const* raw) but is granted to
+ * return a constant reverse iterator even for handles that are not
+ * const-qualified.
+ */
template <typename T>
static std::reverse_iterator<T const*> crend(Eina_Inarray const* raw)
{
return _inarray_access_traits::rend<T const*>(raw);
}
+
+/**
+ * @brief Check if the given Eina array is empty.
+ * @return @c true if the given array is empty, @c false otherwise.
+ *
+ * This functions returns @c true if the given @c Eina_Inarray contains
+ * no elements, otherwise it returns @c false.
+ */
template <typename T>
static inline bool empty(Eina_Inarray const* raw)
{
return _inarray_access_traits::size<T>(raw) == 0;
}
+
+/**
+ * @brief Get the size of the given @c Eina_Inarray.
+ * @return Number of elements in the given array.
+ *
+ * This function returns the current number of elements inside of @p raw.
+ */
template <typename T>
static inline std::size_t size(Eina_Inarray const* raw)
{
return ::eina_inarray_count(raw);
}
+
+/**
+ * @brief Get a constant reference to the element at the given position.
+ * @param raw Constant pointer to an @c Eina_Inarray.
+ * @param i Position of the element.
+ * @return Constant reference to the element.
+ *
+ * Version of @ref index() for const-qualified @c Eina_Inarray. Returns
+ * a constant reference instead.
+ */
template <typename T>
static T const& index(Eina_Inarray const* raw, std::size_t i)
{
return *(_inarray_access_traits::begin<T>(raw) + i);
}
+
+/**
+ * @brief Get a reference to the element at the given position.
+ * @param raw Pointer to a @c Eina_Inarray.
+ * @param i Position of the element.
+ * @return Reference to the element.
+ *
+ * This member function returns a reference to the element at position
+ * @p i inside @p raw.
+ */
template <typename T>
static T& index(Eina_Inarray* raw, std::size_t i)
{
return *(_inarray_access_traits::begin<T>(raw) + i);
}
+
};
template <typename T>
class inarray;
+/**
+ * @ingroup Eina_Cxx_Range_Group
+ *
+ * Range class for @ref inarray.
+ */
template <typename T>
struct range_inarray : _range_template<T, _inarray_access_traits>
{
- typedef _range_template<T, _inarray_access_traits> _base_type;
- typedef typename std::remove_const<T>::type value_type;
+ typedef _range_template<T, _inarray_access_traits> _base_type; /**< Type for the base class. */
+ typedef typename std::remove_const<T>::type value_type; /**< The type of each element. */
+ /**
+ * @brief Creates a range from a native Eina inline array handle.
+ */
range_inarray(Eina_Inarray* array)
: _base_type(array)
{}
+
+ /**
+ * @brief Creates a range from a @c inarray object.
+ */
range_inarray(inarray<T>& array)
: _base_type(array.native_handle())
{}
+ /**
+ * @brief Get the element at the given position in the array.
+ * @param index Position of the element.
+ * @return Reference to the element at the given position.
+ */
value_type& operator[](std::size_t index) const
{
return _inarray_access_traits::index<T>(this->native_handle(), index);
}
};
+/**
+ * Common inarray interface for every value type.
+ */
struct _inarray_common_base
{
- typedef std::size_t size_type;
- typedef Eina_Inarray* native_handle_type;
- typedef Eina_Inarray const* const_native_handle_type;
+ typedef std::size_t size_type; /**< Type for size information used in the array. */
+ typedef Eina_Inarray* native_handle_type; /** Type for the native @c Eina_Inarray handle. */
+ typedef Eina_Inarray const* const_native_handle_type; /** Type for constant native @c Eina_Inarray handle. */
+ /**
+ * @brief Creates a new array object from a handle to a native @c Eina_Inarray.
+ * @param array Handler to a native @c Eina_Inarray
+ *
+ * This constructor wraps a pre-allocated @c Eina_Inarray providing an
+ * OO interface to it.
+ *
+ * @warning It is important to note that the created array object
+ * gains ownership of the handle, deallocating it at destruction time.
+ */
explicit _inarray_common_base(Eina_Inarray* array)
: _array(array) {}
+
+ /**
+ * @brief Allocates a array with the given size for each element.
+ * @param member_size Size of each element in the array.
+ *
+ * This constructor creates an inline array object with the given
+ * size (in bytes) for each element. All allocated memory will be
+ * released at destruction.
+ */
explicit _inarray_common_base(size_type member_size)
: _array( ::eina_inarray_new(member_size, 0) )
{
}
+
+ /**
+ * @brief Release the inline array memory.
+ *
+ * This destructor release the internal native @c Eina_Inarray handle,
+ * freeing allocated memory.
+ */
~_inarray_common_base()
{
::eina_inarray_free(_array);
}
-
+
+ /**
+ * @brief Get the current size of the array.
+ * @return Number of elements in the array.
+ *
+ * This member function returns the current number of elements inside
+ * the inline array.
+ */
size_type size() const
{
return _inarray_access_traits::size<void>(_array);
}
+
+ /**
+ * @brief Check if the array is empty.
+ * @return @c true if the array is empty, @c false otherwise.
+ *
+ * This member function returns @c true if the array does not contain
+ * any elements, otherwise it returns @c false.
+ */
bool empty() const
{
return _inarray_access_traits::empty<void>(_array);
}
+
+ /**
+ * @brief Get the handle for the wrapped Eina_Inarray.
+ * @return Internal handle for the native Eina inline array.
+ *
+ * This member function returns the native @c Eina_Inarray handle that
+ * is wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
native_handle_type native_handle() { return _array; }
+
+ /**
+ * @brief Get a constant handle for the wrapped Eina_Inarray.
+ * @return Constant handle for the native Eina inline array.
+ *
+ * Version of @ref native_handle() for const-qualified objects.
+ * Return a constant handle instead.
+ */
const_native_handle_type native_handle() const { return _array; }
+ /**
+ * @internal
+ * Member variable that holds the native @c Eina_Inarray handle.
+ */
Eina_Inarray* _array;
private:
+ /** Disabled copy constructor. */
_inarray_common_base(_inarray_common_base const& other);
+ /** Disabled assignment operator. */
_inarray_common_base& operator=(_inarray_common_base const& other);
};
+/**
+ * Optimized specialization of the base inline array for POD types.
+ */
template <typename T>
class _pod_inarray : _inarray_common_base
{
- typedef _inarray_common_base _base_type;
+ typedef _inarray_common_base _base_type; /**< Type for the base class. */
public:
- typedef T value_type;
- typedef T& reference;
- typedef T const& const_reference;
- typedef T* pointer;
- typedef T const* const_pointer;
+ typedef T value_type; /**< The type of each element. */
+ typedef T& reference; /**< Type for a reference to an element. */
+ typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef T* pointer; /**< Type for a pointer to an element. */
+ typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
+
+ /**
+ * Type for a iterator for this container.
+ * Defined as a @ref pointer for performance reasons.
+ */
typedef pointer iterator;
+
+ /**
+ * Type for a constant iterator for this container.
+ * Defined as a @ref const_pointer for performance reasons.
+ */
typedef const_pointer const_iterator;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef _base_type::native_handle_type native_handle_type;
- typedef _base_type::const_native_handle_type const_native_handle_type;
+ typedef std::size_t size_type; /**< Type for size information used in the array. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
+ typedef _base_type::native_handle_type native_handle_type; /** Type for the native @c Eina_Inarray handle. */
+ typedef _base_type::const_native_handle_type const_native_handle_type; /** Type for constant native @c Eina_Inarray handle. */
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator of the array. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /** Type for constant reverse iterator of the array. */
- using _base_type::size;
- using _base_type::empty;
- using _base_type::native_handle;
+ using _base_type::size; /**< Type for size information used in the array. */
+
+ /**
+ * @brief Check if the array is empty.
+ * @return @c true if the array is empty, @c false otherwise.
+ *
+ * This member function returns @c true if the array does not contain
+ * any elements, otherwise it returns @c false.
+ */
+ using _base_type::empty;
+ using _base_type::native_handle; /** Type for the native @c Eina_Inarray handle. */
+
+ /**
+ * @brief Create a new object from a handle to a native @c Eina_Inarray.
+ * @param array Handler to a native @c Eina_Inarray.
+ *
+ * This constructor wraps a pre-allocated @c Eina_Inarray providing an
+ * OOP interface to it.
+ *
+ * @warning It is important to note that the created object gains
+ * ownership of the handle, deallocating it at destruction time.
+ */
_pod_inarray(Eina_Inarray* array)
: _base_type(array) {}
+
+ /**
+ * @brief Default constructor. Create an empty array.
+ *
+ * This constructor creates an array object with no elements. Elements
+ * are declarated as having the same size of the given template
+ * typename argument.
+ */
_pod_inarray() : _base_type(sizeof(T))
{
}
+
+ /**
+ * @brief Construct an array object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates an inline array with @p n elements, each
+ * one as a copy of @p t.
+ */
_pod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
{
while(n--)
push_back(t);
}
+
+ /**
+ * @brief Create a inline array with elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ *
+ * This constructor creates a inline array with copies of the elements
+ * between @p i and @p j in the same order.
+ *
+ * @note The ending element (pointed by @p j) is not copied.
+ */
template <typename InputIterator>
_pod_inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
++i;
}
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given inline array.
+ * @param other Another inline array of the same type.
+ *
+ * This constructor creates an inline array containing a copy of each
+ * element inside @p other in the same order.
+ */
_pod_inarray(_pod_inarray<T>const& other)
: _base_type(sizeof(T))
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * Do nothing, the native @c Eina_Inarray is already released in the
+ * base class destructor.
+ */
~_pod_inarray()
{
}
+
+ /**
+ * @brief Replace the current content with the cotent of another array.
+ * @param other Another inline array of the same type.
+ *
+ * This assignment operator replaces the content of the array by a
+ * copy of the content of @p other. The array size is adjusted
+ * accordingly and the newly copied elements keep their original order.
+ */
_pod_inarray<T>& operator=(_pod_inarray<T>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
+
+ /**
+ * @brief Remove all the elements of the array.
+ */
void clear()
{
::eina_inarray_flush(_array);
}
+
+ /**
+ * @brief Add a copy of the given element at the end of the array.
+ * @param value Element to be added at the end of the array.
+ *
+ * This member function allocates a new element at the end of the
+ * inline array, the content of @p value is copied to the new element.
+ */
void push_back(T const& value)
{
size_type s = size();
assert(size() != s);
assert(size() == s + 1u);
}
+
+ /**
+ * @brief Remove the last element of the array.
+ */
void pop_back()
{
eina_inarray_pop(_array);
}
+
+ /**
+ * @brief Insert a new element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param t Value to be copied to the new element.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function inserts a copy of the element @p t at the
+ * position @p i. The new element comes right before the element
+ * originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ */
iterator insert(iterator i, value_type const& t)
{
if(i != end())
return end()-1;
}
}
+
+ /**
+ * @brief Insert @p n copies of @p t at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param t Value to be copied to each new inserted element.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts @p n new elements at position @p i
+ * in the array, each one as a copy of @p t. The new elements come
+ * right before the element originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
iterator insert(iterator i, size_t n, value_type const& t)
{
T* q;
std::memcpy(p, &t, sizeof(t));
return q;
}
+
+ /**
+ * @brief Insert the elements between the given range at the given position.
+ * @param p Iterator pointing to the position where the new elements will be inserted.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts a copy of the elements between @p i
+ * and @p j at the position @p p. The new elements come right before
+ * the element originally pointed by @p p. Note that the element
+ * pointed by @p j is not copied.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
}
return p - n;
}
+
+ /**
+ * @brief Remove the element at the given position.
+ * @param q Iterator pointing to the element to be removed.
+ * @return Iterator pointing to the element after the removed one.
+ *
+ * This member function removes the element pointed by the iterator
+ * @p q, reducing the array size by one. At the end, a valid iterator
+ * pointing to the element right after the removed one is returned.
+ */
iterator erase(iterator q)
{
::eina_inarray_remove_at(_array, q - begin());
return q;
}
+
+ /**
+ * @brief Remove the elements between the given range.
+ * @param i Iterator pointing to the starting position to be removed.
+ * @param j Iterator pointing to the ending position to be removed.
+ * The element pointed by this iterator is not removed.
+ * @return Iterator pointing to the new position of the first
+ * non-removed element after the removed ones (i.e. the one
+ * originally pointed by @p j).
+ *
+ * This member function removes the elements between the iterators
+ * @p i and @p j, including the element pointed by @p i but not the
+ * element pointed by @j.
+ */
iterator erase(iterator i, iterator j)
{
while(i != j)
}
return i;
}
+
+ /**
+ * @brief Replace the content of the array by the elements in the given range.
+ * @param i Iterator pointing to the beginning of the elements to be copied.
+ * @param j Iterator pointing to the end of the elements to be copied.
+ * Note that the element pointed by j will NOT be copied.
+ *
+ * This member function replaces the current elements by copies of the
+ * elements between the iterators @p i and @p j, including the element
+ * pointed by @p i but not the one pointed by @p j. The size of the
+ * array is adjusted accordingly and the newly copied elements remain
+ * in their original order.
+ */
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
+
+ /**
+ * @brief Replace the content of the array by @p n copies @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ */
void assign(size_type n, value_type const& t);
+
+ /**
+ * @brief Get a reference to the element at the given position.
+ * @param i Position of the element.
+ * @return Reference to the element at the ith position.
+ */
value_type& operator[](size_type i)
{
return *(begin() + i);
}
+
+ /**
+ * @brief Get a constant reference to the element at the given position.
+ * @param i Position of the element.
+ * @return Constant reference to the element at the ith position.
+ *
+ * Version of @ref operator[](size_type i) for const-qualified inline
+ * array objects. Returns a constant reference instead.
+ */
value_type const& operator[](size_type i) const
{
return const_cast<inarray<T>&>(*this)[i];
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element in the array.
+ */
value_type& back()
{
return _inarray_access_traits::back<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element in the array.
+ *
+ * Version of @ref back() for const-qualified inline array objects.
+ * Returns a constant reference instead.
+ */
value_type const& back() const
{
return _inarray_access_traits::back<value_type>(_array);
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the array.
+ */
value_type& front()
{
return _inarray_access_traits::front<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the array.
+ *
+ * Version of @ref front() for const-qualified inline array objects.
+ * Returns a constant reference instead.
+ */
value_type const& front() const
{
return _inarray_access_traits::front<value_type>(_array);
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the array.
+ * @return Iterator to the initial position of the array.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the array. If the array is empty the returned iterator
+ * is the same as the one returned by @ref end().
+ */
iterator begin()
{
return _inarray_access_traits::begin<value_type>(_array);
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the array.
+ * @return Iterator to the final position of the array.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the array. If the array is empty the returned
+ * iterator is the same as the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end()
{
return _inarray_access_traits::end<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * Version of @ref begin() for const-qualified inline array objects.
+ * Returns a constant iterator instead.
+ */
const_iterator begin() const
{
return _inarray_access_traits::begin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * Version of @ref end() for const-qualified inline array objects.
+ * Returns a constant iterator instead.
+ */
const_iterator end() const
{
return _inarray_access_traits::end<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * Version of @ref rbegin() for const-qualified inline array objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rbegin() const
{
return _inarray_access_traits::rbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * Version of @ref rend() for const-qualified inline array objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rend() const
{
return _inarray_access_traits::rend<value_type>(_array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the array.
+ * @return Reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the array. If the array is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin()
{
return _inarray_access_traits::rbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the array.
+ * @return Reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the array. If the array is
+ * empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend()
{
return _inarray_access_traits::rend<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * This member function works like @ref begin() const but is granted
+ * to return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
const_iterator cbegin() const
{
return _inarray_access_traits::cbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * This member function works like @ref end() const but is granted to
+ * return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
const_iterator cend() const
{
return _inarray_access_traits::cend<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function works like @ref rbegin() const but is granted
+ * to return a constant reverse iterator even for arrays that are not
+ * const-qualified.
+ */
const_reverse_iterator crbegin() const
{
return _inarray_access_traits::crbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function works like @ref rend() const but is granted to
+ * return a constant reverse iterator even for arrays that are not
+ * const-qualified.
+ */
const_reverse_iterator crend() const
{
return _inarray_access_traits::crend<value_type>(_array);
}
+
+ /**
+ * @brief Swap content between two inline arrays.
+ * @param other Other inline array of the same type.
+ */
void swap(_pod_inarray<T>& other)
{
std::swap(_array, other._array);
}
+
+ /**
+ * @brief Get the maximum number of elements a inline array can hold.
+ * @return Maximum number of elements a inline array can hold.
+ */
size_type max_size() const { return -1; }
+ /**
+ * @brief Get a handle for the wrapped Eina_Inarray.
+ * @return Handle for the native Eina inline array.
+ *
+ * This member function returns the native Eina_Inarray handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
Eina_Inarray* native_handle()
{
return this->_array;
}
+
+ /**
+ * @brief Get a constant handle for the wrapped Eina_Inarray.
+ * @return Constant handle for the native Eina inline array.
+ *
+ * Version of @ref native_handle() for const-qualified objects.Returns
+ * a constant handle instead.
+ *
+ * @see native_handle()
+ */
Eina_Inarray const* native_handle() const
{
return this->_array;
template <typename T>
class _nonpod_inarray : _inarray_common_base
{
- typedef _inarray_common_base _base_type;
+ typedef _inarray_common_base _base_type; /**< Type for the base class. */
public:
- typedef T value_type;
- typedef T& reference;
- typedef T const& const_reference;
- typedef T* pointer;
- typedef T const* const_pointer;
+ typedef T value_type; /**< The type of each element. */
+ typedef T& reference; /**< Type for a reference to an element. */
+ typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef T* pointer; /**< Type for a pointer to an element. */
+ typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
+
+ /**
+ * Type for a iterator to this kind of inline array.
+ * Defined as a @ref pointer for performance reasons.
+ */
typedef pointer iterator;
+
+ /**
+ * Type for a constant iterator for this kind of inline array.
+ * Defined as a @ref const_pointer for performance reasons.
+ */
typedef const_pointer const_iterator;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type; /**< Type for size information used in the array. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator; /** Type for the native @c Eina_Inarray handle. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /** Type for constant native @c Eina_Inarray handle. */
using _base_type::size;
using _base_type::empty;
+ /**
+ * @brief Create a new object from a handle to a native Eina_Inarray.
+ * @param array Handle to a native Eina_Inarray.
+ *
+ * This constructor wraps a pre-allocated Eina_Inarray providing an
+ * OOP interface to it.
+ *
+ * @warning It is important to note that the created object gains
+ * ownership of the handle, deallocating it at destruction time.
+ */
_nonpod_inarray(Eina_Inarray* array)
: _base_type(array) {}
+
+ /**
+ * @brief Default constructor. Create an empty array.
+ *
+ * This constructor creates an array object with no elements. Elements
+ * are declarated as having the same size of the given template
+ * typename argument.
+ */
_nonpod_inarray() : _base_type(sizeof(T))
{
}
+
+ /**
+ * @brief Construct an array object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates an inline array with @p n elements, each
+ * one as a copy of @p t.
+ */
_nonpod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
{
while(n--)
push_back(t);
}
+
+ /**
+ * @brief Create a inline array coping the elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ *
+ * This constructor creates a inline array with copies of the elements
+ * between @p i and @p j in the same order. Note that the ending
+ * element (pointed by @p j) is excluded.
+ */
template <typename InputIterator>
_nonpod_inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
++i;
}
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given inline array.
+ * @param other Another inline array of the same type.
+ *
+ * This constructor creates an inline array containing a copy of each
+ * element inside @p other in the same order.
+ */
_nonpod_inarray(_nonpod_inarray<T>const& other)
: _base_type(sizeof(T))
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Destructor of array for non-POD elements.
+ *
+ * Calls the destructor of each allocated element, before the base
+ * class destructor releases their memory.
+ */
~_nonpod_inarray()
{
for(T* first = static_cast<T*>(_array->members)
, *last = first + _array->len; first != last; ++first)
first->~T();
}
+
+ /**
+ * @brief Replace current content with the cotent of another array.
+ * @param other Another inline array of the same type.
+ *
+ * This assignment operator replaces the content of the array by a
+ * copy of the content of the given array @p other. The array size is
+ * adjusted accordingly and the newly copied elements keep their
+ * original order.
+ */
_nonpod_inarray<T>& operator=(_nonpod_inarray<T>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
+
+ /**
+ * @brief Remove all the elements of the array.
+ */
void clear()
{
for(T* first = static_cast<T*>(_array->members)
first->~T();
::eina_inarray_flush(_array);
}
+
+ /**
+ * @brief Add a copy of the given element at the end of the array.
+ * @param value Element to be added at the end of the array.
+ *
+ * This member function allocates a new element at the end of the
+ * inline array, the content of @p value is copied to the new element.
+ */
void push_back(T const& value)
{
insert(end(), 1u, value);
}
+
+ /**
+ * @brief Remove the last element of the array.
+ */
void pop_back()
{
T* elem = static_cast<T*>(_array->members) + _array->len - 1;
elem->~T();
eina_inarray_pop(_array);
}
+
+ /**
+ * @brief Insert a new element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param t Value to be copied to the new element.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function inserts a copy of the element @p t at the
+ * position @p i. The new element comes right before the element
+ * originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ */
iterator insert(iterator i, value_type const& t)
{
return insert(i, 1u, t);
}
+
+ /**
+ * @brief Insert @p n copies of @p t at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param t Value to be copied to each new inserted element.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts @p n new elements at position @p i
+ * in the array, each one as a copy of @p t. The new elements come
+ * right before the element originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
iterator insert(iterator i, size_t n, value_type const& t)
{
if(_array->max - _array->len >= n)
, first = begin()
, last = first + _array->len;
i = index + begin();
-
+
while(first != i)
{
new (&*first++) T(*old_first);
}
return i;
}
+
+ /**
+ * @brief Insert the elements between the given range at the given position.
+ * @param p Iterator pointing to the position where the new elements will be inserted.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts a copy of the elements between @p i
+ * and @p j at the position @p p. The new elements come right before
+ * the element originally pointed by @p p. Note that the element
+ * pointed by @p j is not copied.
+ */
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
}
return p - n;
}
+
+ /**
+ * @brief Remove the element at the given position.
+ * @param q Iterator pointing to the element to be removed.
+ * @return Iterator pointing to the element after the removed one.
+ *
+ * This member function removes the element pointed by the iterator
+ * @p q, reducing the array size by one. At the end, a valid iterator
+ * pointing to the element right after the removed one is returned.
+ */
iterator erase(iterator q)
{
return erase(q, q+1);
}
+
+ /**
+ * @brief Remove the elements between the given range.
+ * @param i Iterator pointing to the starting position to be removed.
+ * @param j Iterator pointing to the ending position to be removed.
+ * The element pointed by this iterator is not removed.
+ * @return Iterator pointing to the new position of the first
+ * non-removed element after the removed ones (i.e. the one
+ * originally pointed by j).
+ *
+ * This member function removes the elements between the iterators
+ * @p i and @p j, including the element pointed by @p i but not the
+ * element pointed by @j.
+ */
iterator erase(iterator i, iterator j)
{
iterator last = end();
return i;
}
+
+ /**
+ * @brief Replace the content of the array by the elements in the given range.
+ * @param i Iterator pointing to the beginning of the elements to be copied.
+ * @param j Iterator pointing to the end of the elements to be copied.
+ * Note that the element pointed by j will NOT be copied.
+ *
+ * This member function replaces the current elements by copies of the
+ * elements between the iterators @p i and @p j, including the element
+ * pointed by @p i but not the one pointed by @p j. The size of the
+ * array is adjusted accordingly and the newly copied elements remain
+ * in their original order.
+ */
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
+
+ /**
+ * @brief Replace the content of the array by @p n copies @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ */
void assign(size_type n, value_type const& t);
+
+ /**
+ * @brief Get a reference to the element at the given position.
+ * @param i Position of the element.
+ * @return Reference to the element at the ith position.
+ */
value_type& operator[](size_type i)
{
return *(begin() + i);
}
+
+
+ /**
+ * @brief Get a constant reference to the element at the given position.
+ * @param i Position of the element.
+ * @return Constant reference to the element at the ith position.
+ *
+ * Version of @ref operator[](size_type i) for const-qualified inline
+ * array objects. Return a constant reference instead.
+ */
value_type const& operator[](size_type i) const
{
return const_cast<inarray<T>&>(*this)[i];
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element in the array.
+ */
value_type& back()
{
return _inarray_access_traits::back<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element in the array.
+ *
+ * Version of @ref back() for const-qualified inline array objects.
+ * Return a constant reference instead.
+ */
value_type const& back() const
{
return _inarray_access_traits::back<value_type>(_array);
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the array.
+ */
value_type& front()
{
return _inarray_access_traits::front<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the array.
+ *
+ * Version of @ref front() for const-qualified inline array objects.
+ * Return a constant reference instead.
+ */
value_type const& front() const
{
return _inarray_access_traits::front<value_type>(_array);
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the array.
+ * @return Iterator to the initial position of the array.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the array. If the array is empty the returned iterator
+ * is the same as the one returned by @ref end().
+ */
iterator begin()
{
return _inarray_access_traits::begin<value_type>(_array);
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the array.
+ * @return Iterator to the final position of the array.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the array. If the array is empty the returned
+ * iterator is the same as the one returned by @ref begin().
+ * Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end()
{
return _inarray_access_traits::end<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * Version of @ref begin() for const-qualified inline array objects.
+ * Returns a constant iterator instead.
+ */
const_iterator begin() const
{
return _inarray_access_traits::begin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * Version of @ref end() for const-qualified inline array objects.
+ * Returns a constant iterator instead.
+ */
const_iterator end() const
{
return _inarray_access_traits::end<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * Version of @ref rbegin() for const-qualified inline array objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rbegin() const
{
return _inarray_access_traits::rbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * Version of @ref rend() for const-qualified inline array objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rend() const
{
return _inarray_access_traits::rend<value_type>(_array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the array.
+ * @return Reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the array. If the array is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin()
{
return _inarray_access_traits::rbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the array.
+ * @return Reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the array. If the array is
+ * empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend()
{
return _inarray_access_traits::rend<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * This member function works like the constant overload of @ref begin()
+ * but is granted to return a constant iterator even for arrays that
+ * are not const-qualified.
+ */
const_iterator cbegin() const
{
return _inarray_access_traits::cbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * This member function works like the constant overload of @ref end()
+ * but is granted to return a constant iterator even for arrays that
+ * are not const-qualified.
+ */
const_iterator cend() const
{
return _inarray_access_traits::cend<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function works like the constant overload of @ref rbegin()
+ * but is granted to return a constant reverse iterator even for
+ * arrays that are not const-qualified.
+ */
const_reverse_iterator crbegin() const
{
return _inarray_access_traits::crbegin<value_type>(_array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function works like the constant overload of @ref rend()
+ * but is granted to return a constant reverse iterator even for
+ * arrays that are not const-qualified.
+ */
const_reverse_iterator crend() const
{
return _inarray_access_traits::crend<value_type>(_array);
}
+
+ /**
+ * @brief Swap content between two inline arrays.
+ * @param other Other inline array of the same type.
+ */
void swap(_nonpod_inarray<T>& other)
{
std::swap(_array, other._array);
}
+
+ /**
+ * @brief Get the maximum number of elements a inline array can hold.
+ * @return Maximum number of elements a inline array can hold.
+ */
size_type max_size() const { return -1; }
+ /**
+ * @brief Get the handle for the wrapped Eina_Inarray.
+ * @return Internal handle for the native Eina inline array.
+ *
+ * This member function returns the native Eina_Inarray handle that is
+ * wrapped inside this object. It is important to take care when using
+ * it, since the handle will be automatically release upon object
+ * destruction.
+ */
Eina_Inarray* native_handle()
{
return this->_array;
}
+
+ /**
+ * @brief Get the handle for the wrapped Eina_Inarray.
+ * @return Internal handle for the native Eina inline array.
+ *
+ * This member function returns the native Eina_Inarray handle that is
+ * wrapped inside this object. It is important to take care when using
+ * it, since the handle will be automatically release upon object
+ * destruction.
+ */
Eina_Inarray const* native_handle() const
{
return this->_array;
}
};
+
+/**
+ * Inline array class. It provides an OOP interface to the
+ * @c Eina_Inarray functions, and automatically take care of allocating
+ * and deallocating resources using the RAII programming idiom.
+ *
+ * It also provides additional member functions to facilitate the access
+ * to the array content, much like a STL vector.
+ */
template <typename T>
class inarray : public eina::if_<eina::is_pod<T>, _pod_inarray<T>
, _nonpod_inarray<T> >::type
{
typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T>
- , _nonpod_inarray<T> >::type _base_type;
+ , _nonpod_inarray<T> >::type _base_type; /**< Type for the base class. */
public:
+
+ /**
+ * @brief Create a new object from a handle to a native Eina_Inarray.
+ * @param array Handle to a native Eina_Inarray.
+ *
+ * This constructor wraps a pre-allocated Eina_Inarray providing an
+ * OOP interface to it.
+ *
+ * @warning It is important to note that the created object gains
+ * ownership of the handle, deallocating it at destruction time.
+ */
inarray(Eina_Inarray* array)
: _base_type(array) {}
+
+ /**
+ * @brief Default constructor. Creates an empty array.
+ */
inarray() : _base_type() {}
+
+ /**
+ * @brief Construct an array object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates an inline array with @p n elements, each
+ * one as a copy of @p t.
+ */
inarray(typename _base_type::size_type n, typename _base_type::value_type const& t)
: _base_type(n, t) {}
+
+ /**
+ * @brief Create a inline array with elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ *
+ * This constructor creates a inline array with copies of the elements
+ * between @p i and @p j in the same order.
+ *
+ * @note The ending element (pointed by @p j) is not copied.
+ */
template <typename InputIterator>
inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(i, j)
{}
-
+
};
+/**
+ * @brief Check if two inline arrays are equal.
+ * @param lhs Inline array at the left side of the expression.
+ * @param rhs Inline array at the right side of the expression.
+ * @return @c true if the arrays are equals, @c false otherwise.
+ *
+ * This operator checks if the given inline arrays are equal. To be
+ * considered equal both arrays need to have the same number of
+ * elements, and each element in one array must be equal to the element
+ * at the same position in the other array.
+ */
template <typename T>
bool operator==(inarray<T> const& lhs, inarray<T> const& rhs)
{
std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
+/**
+ * @brief Check if two inline arrays are different.
+ * @param lhs Inline array at the left side of the expression.
+ * @param rhs Inline array at the right side of the expression.
+ * @return @c true if the arrays are not equal , @c false otherwise.
+ *
+ * This operator returns the opposite of @ref operator==(inarray<T> const& lhs, inarray<T> const& rhs).
+ */
template <typename T>
bool operator!=(inarray<T> const& lhs, inarray<T> const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Swap content between two inline arrays.
+ * @param other Other inline array of the same type.
+ */
template <typename T>
void swap(inarray<T>& lhs, inarray<T>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
} }
+/**
+ * @}
+ */
+
#endif
#include <iterator>
#include <algorithm>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Inline_List_Group Inline List
+ * @ingroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
+/**
+ * @internal
+ */
template <typename T>
struct _inlist_node
{
T object;
};
+/**
+ * @internal
+ */
template <typename T>
_inlist_node<T>* _get_node(Eina_Inlist* l)
{
return static_cast<_inlist_node<T>*>(static_cast<void*>(l));
}
+/**
+ * @internal
+ */
template <typename T>
_inlist_node<T> const* _get_node(Eina_Inlist const* l)
{
return const_cast<Eina_Inlist*>(l);
}
+/**
+ * @internal
+ */
template <typename T>
Eina_Inlist* _get_list(_inlist_node<T>* n)
{
return 0;
}
+/**
+ * @internal
+ */
template <typename T>
Eina_Inlist const* _get_list(_inlist_node<T> const* n)
{
return _get_list(const_cast<_inlist_node<T>*>(n));
}
+/**
+ * @internal
+ * Iterator for Inline List
+ */
template <typename T>
struct _inlist_iterator
{
- typedef typename std::remove_const<T>::type value_type;
- typedef value_type* pointer;
- typedef value_type& reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::bidirectional_iterator_tag iterator_category;
+ typedef typename std::remove_const<T>::type value_type; /**< Type for the list elements. */
+ 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::bidirectional_iterator_tag iterator_category; /**< Defines the iterator as being a bidirectional iterator. */
+ /**
+ * @brief Default constructor. Creates an uninitialized iterator.
+ */
_inlist_iterator() {}
+
+ /**
+ * @brief Creates an iterator from a inline list and a node.
+ * @param list Pointer to the inline list.
+ * @param node Pointer to the node.
+ */
explicit _inlist_iterator(_inlist_node<value_type>* list, _inlist_node<value_type>* node)
: _list(list), _node(node) {}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given iterator.
+ * @param other Other iterator.
+ */
_inlist_iterator(_inlist_iterator<typename std::remove_const<T>::type> const& other)
: _list(other._list), _node(other._node) {}
+ /**
+ * @brief Move the iterator to the next position in the list.
+ * @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.
+ */
_inlist_iterator<T>& operator++()
{
_node = _get_node<value_type>(_node->__in_list.next);
return *this;
}
+
+ /**
+ * @brief Move the iterator to the next position in the list.
+ * @return Copy of the iterator before the increment.
+ *
+ * This operator increments the iterator, making it point to the next
+ * position right after the current one.
+ * At the end, it returns a copy of the iterator before the increment.
+ */
_inlist_iterator<T> operator++(int)
{
_inlist_iterator<T> tmp(*this);
++*this;
return tmp;
}
+
+ /**
+ * @brief Move the iterator to the previous position in the list.
+ * @return The iterator itself.
+ *
+ * This operator decrements the iterator, making it point to the
+ * position right before the current one.
+ * At the end, it returns a reference to itself.
+ */
_inlist_iterator<T>& operator--()
{
if(_node)
_node = _get_node<value_type>(_list->__in_list.last);
return *this;
}
+
+ /**
+ * @brief Move the iterator to the previous position in the list.
+ * @return Copy of the iterator before the decrement.
+ *
+ * This operator decrements the iterator, making it point to the
+ * position right before the current one.
+ * At the end, it returns a copy of the iterator before the decrement.
+ */
_inlist_iterator<T> operator--(int)
{
_inlist_iterator<T> tmp(*this);
--*this;
return tmp;
}
+
+ /**
+ * @brief Get a reference to the element currently pointed by the iterator.
+ * @return Reference to the current element.
+ */
T& operator*() const
{
return _node->object;
}
+
+ /**
+ * @brief Return a pointer to the current element, which member will be accessed.
+ * @return Pointer to the element currently pointed by the iterator.
+ */
T* operator->() const
{
return &_node->object;
}
+
+ /**
+ * @internal
+ */
_inlist_node<value_type>* native_handle()
{
return _node;
}
+
+ /**
+ * @internal
+ */
_inlist_node<value_type> const* native_handle() const
{
return _node;
}
private:
- _inlist_node<value_type>* _list;
- _inlist_node<value_type>* _node;
+ _inlist_node<value_type>* _list; /**< Handle to the original list. */
+ _inlist_node<value_type>* _node; /**< Handle to the current node. */
+ /**
+ * @brief Check if both iterators are pointing to the same node.
+ * @param lhs First iterator to be compared.
+ * @param rhs Second iterator to be compared.
+ * @return @c true if both iterators are pointing to the same node, @c false otherwise.
+ */
template <typename U>
friend struct _inlist_iterator;
friend bool operator==(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
}
};
+/**
+ * @brief Check if iterators are not pointing to the same node.
+ * @param lhs First iterator to be compared.
+ * @param rhs Second iterator to be compared.
+ * @return @c true if iterators are not pointing to the same node, @c false otherwise.
+ */
template <typename T>
bool operator!=(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
{
return !(lhs == rhs);
}
+/**
+ * @internal
+ */
struct _inlist_access_traits {
template <typename T>
struct const_iterator
template <typename T, typename Allocator>
class inlist;
+/**
+ * @ingroup Eina_Cxx_Range_Group
+ *
+ * Range for inline list elements.
+ */
template <typename T>
struct range_inlist : _range_template<T, _inlist_access_traits>
{
- typedef _range_template<T, _inlist_access_traits> _base_type;
- typedef typename _base_type::value_type value_type;
- typedef typename _base_type::native_handle_type native_handle_type;
+ typedef _range_template<T, _inlist_access_traits> _base_type; /**< Type for the base class. */
+ typedef typename _base_type::value_type value_type; /**< The type of each element. */
+ typedef typename _base_type::native_handle_type native_handle_type; /** Type for the native Eina inline list handle. */
+ /**
+ * @brief Creates a range from a native Eina inline list handle.
+ */
range_inlist(native_handle_type list)
: _base_type(list) {}
+
+ /**
+ * @brief Creates a range from a inline list object.
+ */
template <typename Allocator>
range_inlist(inlist<value_type, Allocator>& list)
: _base_type(list.native_handle())
{}
};
+/**
+ * @brief Check the given ranges are equal to each other.
+ * @param lhs Range object at the left side of the expression.
+ * @param rhs Range object at the right side of the expression.
+ * @return @c true if the ranges are equal, @c false otherwise.
+ *
+ * This operator checks if the given ranges are equal to each other. To
+ * be considered equal both ranges need to have the same size, and each
+ * element in one range must be equal to the element at the same
+ * position in the other.
+ */
template <typename T>
bool operator==(range_inlist<T>const& lhs, range_inlist<T>const& rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
+/**
+ * @brief Returns the opposite of @ref operator==(range_inlist<T>const& lhs, range_inlist<T>const& rhs).
+ */
template <typename U>
bool operator!=(range_inlist<U> const& lhs, range_inlist<U>const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * Common implementations for inline list.
+ */
template <typename T, typename Allocator>
struct _inlist_common_base
{
- typedef typename Allocator::template rebind<_inlist_node<T> >::other node_allocator_type;
- typedef Allocator allocator_type;
- typedef _inlist_node<T> node_type;
+ typedef typename Allocator::template rebind<_inlist_node<T> >::other node_allocator_type; /**< Type for the allocator of the node. */
+ typedef Allocator allocator_type; /**< Type for the allocator. */
+ typedef _inlist_node<T> node_type; /**< Type for the list node. */
+ /**
+ * @brief Creates a list with the given allocator.
+ * @param allocator Allocator object.
+ */
_inlist_common_base(Allocator allocator)
: _impl(allocator) {}
+
+ /**
+ * @brief Creates an empty inline list.
+ */
_inlist_common_base()
{}
+
+ /**
+ * @brief Destructor. Deallocate all nodes of the list.
+ */
~_inlist_common_base()
{
clear();
}
+ /**
+ * @brief Deallocate all nodes of the list.
+ */
void clear()
{
Eina_Inlist* p = _impl._list;
}
_impl._list = 0;
}
+
+ /**
+ * @brief Get the allocator used by the list.
+ */
node_allocator_type& get_node_allocator()
{
return _impl;
}
+ /**
+ * @internal
+ */
// For EBO
struct _inlist_impl : node_allocator_type
{
Eina_Inlist* _list;
};
- _inlist_impl _impl;
+ _inlist_impl _impl; /**< @internal */
private:
+
+ /** Disabled copy constructor. */
_inlist_common_base(_inlist_common_base const& other);
+
+ /** Disabled assignment operator. */
_inlist_common_base& operator=(_inlist_common_base const& other);
};
+/**
+ * C++ wrapper for the native Eina inline list.
+ *
+ * It provides an OOP interface to the @c Eina_Inlist functions, and
+ * automatically take care of allocating and deallocating resources using
+ * the RAII programming idiom.
+ *
+ * It also provides additional member functions to facilitate the access
+ * to the list content, much like a STL list.
+ */
template <typename T, typename Allocator = std::allocator<T> >
class inlist : protected _inlist_common_base<T, Allocator>
{
- typedef _inlist_common_base<T, Allocator> _base_type;
- typedef typename _base_type::node_type _node_type;
+ typedef _inlist_common_base<T, Allocator> _base_type; /**< Type for the base class. */
+ typedef typename _base_type::node_type _node_type; /**< Type for each node */
public:
- typedef typename _base_type::allocator_type allocator_type;
- typedef typename allocator_type::value_type value_type;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
- typedef _inlist_iterator<T const> const_iterator;
- typedef _inlist_iterator<T> iterator;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef typename _base_type::allocator_type allocator_type; /**< Type for the allocator. */
+ typedef typename allocator_type::value_type value_type; /**< The type of each element. */
+ typedef typename allocator_type::reference reference; /**< Type for a reference to an element. */
+ typedef typename allocator_type::const_reference const_reference; /**< Type for a constant reference to an element. */
+ typedef _inlist_iterator<T const> const_iterator; /**< Type for constant iterator for this kind of container. */
+ typedef _inlist_iterator<T> iterator; /**< Type for iterator for this kind of container. */
+ typedef typename allocator_type::pointer pointer; /**< Type for a pointer to an element. */
+ typedef typename allocator_type::const_pointer const_pointer; /**< Type for a constant pointer for an element. */
+ typedef std::size_t size_type; /**< Type for size information. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
+
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this kind of container. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for constant reverse iterator for this kind of container. */
using _base_type::clear;
+ /**
+ * @brief Default constructor. Creates an empty inline list.
+ */
inlist() {}
+
+ /**
+ * @brief Construct an inline list object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates an inline list with @p n elements, each
+ * one as a copy of @p t.
+ */
inlist(size_type n, value_type const& t)
{
while(n--)
push_back(t);
}
+
+ /**
+ * @brief Create a inline list coping the elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ *
+ * This constructor creates a inline list with copies of the elements
+ * between @p i and @p j in the same order.
+ *
+ * @note The ending element (pointed by @p j) is not copied.
+ */
template <typename InputIterator>
inlist(InputIterator i, InputIterator const& j
, allocator_type const& alloc = allocator_type()
++i;
}
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given inline list.
+ * @param other Another inline list of the same type.
+ *
+ * This constructor creates an inline list containing a copy of each
+ * element inside @p other in the same order.
+ */
inlist(inlist<T, Allocator>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Replace current content with the content of another inline list.
+ * @param other Another inline list of the same type.
+ *
+ * This assignment operator replaces the content of the list by a copy
+ * of the content of @p other. The list size is adjusted accordingly
+ * and the newly copied elements keep their original order.
+ */
inlist<T, Allocator>& operator=(inlist<T, Allocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
+
+ /**
+ * @brief Get the current size of the inline list.
+ * @return Number of elements in the inline list.
+ *
+ * This member function returns the current number of elements inside
+ * the inline list.
+ */
size_type size() const
{
return _inlist_access_traits::size<T>(native_handle());
}
+
+ /**
+ * @brief Check if the inline list is empty.
+ * @return @c true if the inline list is empty, @c false otherwise.
+ *
+ * This member function returns @c true if the inline list does not
+ * contain any elements, otherwise it returns @c false.
+ */
bool empty() const
{
return _inlist_access_traits::empty<T>(native_handle());
}
+
+ /**
+ * @brief Get the allocator used in this inline list.
+ */
allocator_type get_allocator() const
{
return allocator_type(this->get_node_allocator());
}
+
+ /**
+ * @brief Add a copy of the given element at the end of the inline list.
+ * @param value Element to be added at the end of the inline list.
+ *
+ * This member function allocates a new element at the end of the
+ * inline list, the content of @p value is copied to the new element.
+ */
void push_back(T const& value)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
throw;
}
}
+
+ /**
+ * @brief Add a copy of the given element at the beginning of the inline list.
+ * @param value Element to be added at the beginning of the inline list.
+ *
+ * This member function allocates a new element at the beginning of
+ * the inline list, the content of @p value is copied to the new
+ * element.
+ */
void push_front(T const& value)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
throw;
}
}
+
+ /**
+ * @brief Remove the last element of the inline list.
+ */
void pop_back()
{
this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list->last);
}
+
+ /**
+ * @brief Remove the first element of the inline list.
+ */
void pop_front()
{
this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list);
}
+
+ /**
+ * @brief Insert a new element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param t Value to be copied to the new element.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function inserts a copy of the element @p t at the
+ * position @p i. The new element comes right before the element
+ * originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ */
iterator insert(iterator i, value_type const& t)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
throw;
}
}
+
+ /**
+ * @brief Insert @p n copies of @p t at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param t Value to be copied to each new inserted element.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts @p n new elements at position @p i
+ * in the inline list, each one as a copy of @p t. The new elements
+ * come right before the element originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
return r;
}
+ /**
+ * @brief Insert the elements between the given range at the given position.
+ * @param p Iterator pointing to the position where the new elements will be inserted.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts a copy of the elements between @p i
+ * and @p j at the position @p p. The new elements come right before
+ * the element originally pointed by @p p. Note that the element
+ * pointed by @p j is not copied.
+ */
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
return r;
}
+ /**
+ * @brief Remove the element at the given position.
+ * @param q Iterator pointing to the element to be removed.
+ * @return Iterator pointing to the element after the removed one.
+ *
+ * This member function removes the element pointed by the iterator
+ * @p q, reducing the list size by one. At the end, a valid iterator
+ * pointing to the element right after the removed one is returned.
+ */
iterator erase(iterator q)
{
if(q.native_handle())
return q;
}
+
+ /**
+ * @brief Remove the elements between the given range.
+ * @param i Iterator pointing to the starting position to be removed.
+ * @param j Iterator pointing to the ending position to be removed.
+ * The element pointed by this iterator is not removed.
+ * @return Iterator pointing to the new position of the first
+ * non-removed element after the removed ones (i.e. the one
+ * originally pointed by @p j).
+ *
+ * This member function removes the elements between the iterators
+ * @p i and @p j, including the element pointed by @p i but not the
+ * element pointed by @j.
+ */
iterator erase(iterator i, iterator j)
{
while(i != j)
return end();
}
+ /**
+ * @brief Replace the content of the inline list by the elements in the given range.
+ * @param i Iterator pointing to the beginning of the elements to be copied.
+ * @param j Iterator pointing to the end of the elements to be copied.
+ * Note that the element pointed by j will NOT be copied.
+ *
+ * This member function replaces the current elements by copies of the
+ * elements between the iterators @p i and @p j, including the element
+ * pointed by @p i but not the one pointed by @p j. The size of the
+ * list is adjusted accordingly and the newly copied elements remain
+ * in their original order.
+ */
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
insert(end(), i, j);
}
+ /**
+ * @brief Replace the content of the inline list by @p n copies @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ */
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element in the inline list.
+ */
value_type& back()
{
return _inlist_access_traits::back<T>(native_handle());
}
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element in the inline list.
+ *
+ * Version of @ref back() for const-qualified inline list objects.
+ * Returns a constant reference instead.
+ */
value_type const& back() const
{
return _inlist_access_traits::back<T>(native_handle());
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the inline list.
+ */
value_type& front()
{
return _inlist_access_traits::front<T>(native_handle());
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the inline list.
+ *
+ * Version of @ref front() for const-qualified inline list objects.
+ * Returns a constant reference instead.
+ */
value_type const& front() const
{
return _inlist_access_traits::front<T>(native_handle());
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the inline list.
+ * @return Constant iterator to the initial position of the inline list.
+ *
+ * Version of @ref begin() for const-qualified inline list objects.
+ * Returns a constant iterator instead.
+ */
const_iterator begin() const
{
return _inlist_access_traits::begin<T>(native_handle());
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the inline list.
+ * @return Constant iterator to the final position of the inline list.
+ *
+ * Version of @ref end() for const-qualified inline list objects.
+ * Returns a constant iterator instead.
+ */
const_iterator end() const
{
return _inlist_access_traits::end<T>(native_handle());
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the inline list.
+ * @return Iterator to the initial position of the inline list.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the inline list. If the list is empty the returned
+ * iterator is the same as the one returned by @ref end().
+ */
iterator begin()
{
return _inlist_access_traits::begin<T>(native_handle());
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the inline list.
+ * @return Iterator to the final position of the inline list.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the inline list. If the list is empty the
+ * returned iterator is the same as the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end()
{
return _inlist_access_traits::end<T>(native_handle());
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the inline list.
+ * @return Constant reverse iterator pointing to the reverse begin of the inline list.
+ *
+ * Version of @ref rbegin() for const-qualified inline list objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rbegin() const
{
return reverse_iterator(end());
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the inline list.
+ * @return Constant reverse iterator pointing to the reverse end of the inline list.
+ *
+ * Version of @ref rend() for const-qualified inline list objects.
+ * Returns a constant reverse iterator instead.
+ */
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the inline list.
+ * @return Reverse iterator pointing to the reverse begin of the inline list.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the inline list. If the list is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the inline list.
+ * @return Reverse iterator pointing to the reverse end of the inline list.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the inline list. If the list
+ * is empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend()
{
return reverse_iterator(begin());
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the inline list.
+ * @return Constant iterator to the initial position of the inline list.
+ *
+ * This member function works like @ref begin() const but is granted
+ * to return a constant iterator even for lists that are not
+ * const-qualified.
+ */
const_iterator cbegin() const
{
return begin();
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the inline list.
+ * @return Constant iterator to the final position of the inline list.
+ *
+ * This member function works like @ref end() const but is granted to
+ * return a constant iterator even for lists that are not
+ * const-qualified.
+ */
const_iterator cend() const
{
return end();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the inline list.
+ * @return Constant reverse iterator pointing to the reverse begin of the inline list.
+ *
+ * This member function works like @ref rbegin() const but is granted
+ * to return a constant reverse iterator even for lists that are not
+ * const-qualified.
+ */
const_reverse_iterator crbegin() const
{
return rbegin();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the inline list.
+ * @return Constant reverse iterator pointing to the reverse end of the inline list.
+ *
+ * This member function works like @ref rend() const but is granted to
+ * return a constant reverse iterator even for lists that are not
+ * const-qualified.
+ */
const_reverse_iterator crend() const
{
return rend();
}
+
+ /**
+ * @brief Swap content between two inline lists.
+ * @param other Other inline list of the same type.
+ */
void swap(inlist<T, Allocator>& other)
{
std::swap(this->_impl._list, other._impl._list);
}
+
+ /**
+ * @brief Get the maximum number of elements a inline list can hold.
+ * @return Maximum number of elements a inline list can hold.
+ */
size_type max_size() const { return -1; }
+ /**
+ * @brief Get the handle for the wrapped Eina_Inlist.
+ * @return Internal handle for the native Eina inline list.
+ *
+ * This member function returns the native Eina_Inlist handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
Eina_Inlist* native_handle()
{
return this->_impl._list;
}
+
+ /**
+ * @brief Get the handle for the wrapped Eina_Inlist.
+ * @return Internal handle for the native Eina inline list.
+ *
+ * This member function returns the native Eina_Inlist handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
Eina_Inlist const* native_handle() const
{
return this->_impl._list;
}
+
+ /**
+ * @brief Get a constant @ref eina::accessor for the list.
+ * @return Constant <tt>eina::accessor</tt> to the list.
+ *
+ * Version of @ref accessor() to const-qualified inline lists. Returns
+ * a const-qualified <tt>eina::accessor</tt> instead.
+ */
eina::accessor<T const> accessor() const
{
return eina::accessor<T const>(eina_inlist_accessor_new(this->_impl._list));
}
+
+ /**
+ * @brief Get a @ref eina::accessor for the list.
+ * @return <tt>eina::accessor</tt> to the list.
+ */
eina::accessor<T> accessor()
{
return eina::accessor<T>(eina_inlist_accessor_new(this->_impl._list));
}
};
+/**
+ * @brief Check if two inline lists are equal.
+ * @param lhs Inline list at the left side of the expression.
+ * @param rhs Inline list at the right side of the expression.
+ * @return @c true if the lists are equals, @c false otherwise.
+ *
+ * This operator checks if the given inline lists are equal. To be
+ * considered equal both lists need to have the same number of elements,
+ * and each element in one list must be equal to the element at the same
+ * position in the other list.
+ */
template <typename T, typename Allocator1, typename Allocator2>
bool operator==(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
{
std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
+/**
+ * @brief Return the opposite of @ref operator==(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs).
+ */
template <typename T, typename Allocator1, typename Allocator2>
bool operator!=(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Swap content between two inline lists.
+ * @param other Other inline list of the same type.
+ */
template <typename T, typename Allocator>
void swap(inlist<T, Allocator>& lhs, inlist<T, Allocator>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#ifndef EINA_CXX_EINA_INTEGER_SEQUENCE_HH
#define EINA_CXX_EINA_INTEGER_SEQUENCE_HH
+/**
+ * @addtogroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Integer_Sequence_Group Integer Sequence
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
+/**
+ * Compile-time sequence of integers.
+ */
template <typename T, T... Ints>
struct integer_sequence
{
- typedef T value_type;
+ typedef T value_type; /**< Type of the integers. */
+
+ /**
+ * @brief Get the number of elements in the sequence.
+ * @return <tt>std::size_t</tt> representing the sequence size.
+ */
static constexpr std::size_t size() { return sizeof...(Ints); }
- typedef integer_sequence<T, Ints...> type;
+ typedef integer_sequence<T, Ints...> type; /**< Type for the sequence instantiation. */
};
template<class S1, class S2> struct concat;
+/**
+ * Compile-time concatenation of two integer sequences.
+ */
template<typename T, T... I1, T... I2>
struct concat<integer_sequence<T, I1...>, integer_sequence<T, I2...> >
: integer_sequence<T, I1..., (sizeof...(I1)+I2)...> {};
using Concat = typename concat<S1, S2>::type;
template<typename T, T N> struct gen_seq;
+
+/**
+ * Make a compile time sequence of integers from @c 0 to <tt>N-1</tt>.
+ */
template<typename T, T N> using make_integer_sequence = typename gen_seq<T, N>::type;
template<typename T, T N>
template<> struct gen_seq<std::size_t, 0> : integer_sequence<std::size_t>{};
template<> struct gen_seq<std::size_t, 1> : integer_sequence<std::size_t, 0>{};
+/**
+ * Compile time sequence of indexes.
+ */
template <std::size_t... I>
using index_sequence = integer_sequence<std::size_t, I...>;
+/**
+ * Make a compile time sequence of indexes from @c 0 to <tt>N-1</tt>.
+ */
template <std::size_t I>
using make_index_sequence = make_integer_sequence<std::size_t, I>;
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#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;
+ typedef _common_iterator_base<T> self_type; /**< Type for the iterator instantiation itself. */
public:
- typedef T const value_type;
- typedef value_type* pointer;
- typedef value_type& reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::input_iterator_tag iterator_category;
+ 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;
}
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;
- typename base_type::pointer _value;
- typedef iterator<T> self_type;
+ 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;
- typedef typename base_type::pointer pointer;
- typedef typename base_type::reference reference;
- typedef typename base_type::difference_type difference_type;
- typedef typename base_type::iterator_category iterator_category;
+ 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;
_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
#include <Eina.h>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @internal
+ */
inline Eina_List* _eina_list_prepend_relative_list(Eina_List* list, const void* data, Eina_List* relative) EINA_ARG_NONNULL(2)
{
if(relative)
return ::eina_list_append(list, data);
}
+/**
+ * @internal
+ */
inline Eina_Inlist *_eina_inlist_prepend_relative(Eina_Inlist *in_list,
Eina_Inlist *in_item,
Eina_Inlist *in_relative) EINA_ARG_NONNULL(2)
} }
+/**
+ * @}
+ */
+
#endif
#include <sstream>
+/**
+ * @addtogroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Log_Group Log
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
+/**
+ * Types to represent each log level.
+ *
+ * @{
+ */
namespace log_level {
+/**
+ * Type for representing a critical log level.
+ */
struct critical_t { static constexpr ::Eina_Log_Level value = ::EINA_LOG_LEVEL_CRITICAL; };
+/** Critical log level */
critical_t const critical = {};
+/**
+ * Type for representing an error log level.
+ */
struct error_t { static constexpr ::Eina_Log_Level value = ::EINA_LOG_LEVEL_ERR; };
+/** Error log level */
error_t const error = {};
+/**
+ * Type for representing an information log level.
+ */
struct info_t { static constexpr ::Eina_Log_Level value = ::EINA_LOG_LEVEL_INFO; };
+/** Information log level */
info_t const info = {};
+/**
+ * Type for representing a debug log level.
+ */
struct debug_t { static constexpr ::Eina_Log_Level value = ::EINA_LOG_LEVEL_DBG; };
+/** Debug log level */
debug_t const debug = {};
+/**
+ * Type for representing a warning log level.
+ */
struct warn_t { static constexpr ::Eina_Log_Level value = ::EINA_LOG_LEVEL_WARN; };
+/** Warning log level */
warn_t const warning = {};
}
+/**
+ * @}
+ */
+
+/**
+ * Base implementation for log domains.
+ */
template <typename D>
struct _domain_base
{
+ /**
+ * @brief Set the domain log level based on the given log level type.
+ *
+ * @{
+ */
void set_level(log_level::critical_t l) { set_level(l.value); }
void set_level(log_level::error_t l) { set_level(l.value); }
void set_level(log_level::info_t l) { set_level(l.value); }
void set_level(log_level::debug_t l) { set_level(l.value); }
void set_level(log_level::warn_t l) { set_level(l.value); }
+ /**
+ * @}
+ */
+
+ /**
+ * @brief Set the domain log level to the level specified by the given identifier.
+ * @param l Eina native identifier to a log level.
+ */
void set_level( ::Eina_Log_Level l)
{
::eina_log_domain_registered_level_set(static_cast<D&>(*this).domain_raw(), l);
}
+
+ /**
+ * @brief Get the domain log level.
+ * @return Eina native identifier representing the current log level of the domain.
+ */
::Eina_Log_Level get_level() const
{
return static_cast< ::Eina_Log_Level>
}
};
+/**
+ * @internal
+ */
struct global_domain : _domain_base<global_domain>
{
int domain_raw() const { return EINA_LOG_DOMAIN_GLOBAL; }
};
+/**
+ * General purpose log domain.
+ * It is always registered and available everywhere.
+ */
struct global_domain const global_domain = {};
+/**
+ * @internal
+ */
struct default_domain : _domain_base<default_domain>
{
int domain_raw() const { return EINA_LOG_DOMAIN_DEFAULT; }
};
+/**
+ * Default log domain.
+ * If the macro @c EINA_LOG_DOMAIN_DEFAULT is not defined to anything
+ * different it will be equivalent to @c global_domain.
+ */
struct default_domain const default_domain = {};
+/**
+ * Class for creating log domains. It register a new domain upon
+ * construction and unregister it upon destruction, following the RAII
+ * programming idiom.
+ */
struct log_domain : _domain_base<log_domain>
{
+ /**
+ * @brief Creates a new log domain.
+ * @param name Name of the domain.
+ * @param color Color of the domain name.
+ */
log_domain(char const* name, char const* color = "black")
: _domain( ::eina_log_domain_register(name, color))
{
}
+
+ /**
+ * @brief Unregister the domain.
+ */
~log_domain()
{
::eina_log_domain_unregister(_domain);
}
int domain_raw() const { return _domain; }
private:
+ /**
+ * @internal
+ *
+ * Member variable that holds the domain identifier.
+ */
int _domain;
};
+/**
+ * @internal
+ */
inline void _log(std::stringstream const& stream, int domain, ::Eina_Log_Level level
, const char* file, const char* function, int line)
{
, "%s", stream.str().c_str());
}
+/**
+ * @def EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ *
+ * Logs a message with level %p LEVEL on the domain %p DOMAIN.
+ *
+ * It works like a STL output stream and should be used with the left
+ * shift operator. Example:
+ * \code{.py}
+ * EINA_CXX_DOM_LOG(my_domain, my_log_level) << "My log message.";
+ * \endcode
+ */
#define EINA_CXX_DOM_LOG(DOMAIN, LEVEL) \
for( bool run = ::eina_log_domain_level_check((DOMAIN), LEVEL); run;) \
for(std::stringstream stream; run ; \
, __FILE__, __FUNCTION__, __LINE__), run = false) \
stream
+/**
+ * @def EINA_CXX_DOM_LOG_CRIT(DOMAIN)
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_CRITICAL on the domain
+ * %p DOMAIN.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(DOMAIN, ::EINA_LOG_LEVEL_CRITICAL).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_DOM_LOG_CRIT(DOMAIN) \
EINA_CXX_DOM_LOG(DOMAIN.domain_raw(), ::EINA_LOG_LEVEL_CRITICAL)
+/**
+ * @def EINA_CXX_DOM_LOG_ERR(DOMAIN)
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_ERR on the domain
+ * %p DOMAIN.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(DOMAIN, ::EINA_LOG_LEVEL_ERR).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_DOM_LOG_ERR(DOMAIN) \
EINA_CXX_DOM_LOG(DOMAIN.domain_raw(), ::EINA_LOG_LEVEL_ERR)
+/**
+ * @def EINA_CXX_DOM_LOG_INFO(DOMAIN)
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_INFO on the domain
+ * %p DOMAIN.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(DOMAIN, ::EINA_LOG_LEVEL_INFO).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_DOM_LOG_INFO(DOMAIN) \
EINA_CXX_DOM_LOG(DOMAIN.domain_raw(), ::EINA_LOG_LEVEL_INFO)
+/**
+ * @def EINA_CXX_DOM_LOG_DBG(DOMAIN)
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_DBG on the domain
+ * %p DOMAIN.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(DOMAIN, ::EINA_LOG_LEVEL_DBG).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_DOM_LOG_DBG(DOMAIN) \
EINA_CXX_DOM_LOG(DOMAIN.domain_raw(), ::EINA_LOG_LEVEL_DBG)
+/**
+ * @def EINA_CXX_DOM_LOG_WARN(DOMAIN)
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_WARN on the domain
+ * %p DOMAIN.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(DOMAIN, ::EINA_LOG_LEVEL_WARN).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_DOM_LOG_WARN(DOMAIN) \
EINA_CXX_DOM_LOG(DOMAIN.domain_raw(), ::EINA_LOG_LEVEL_WARN)
+/**
+ * @def EINA_CXX_LOG(LEVEL)
+ *
+ * Logs a message with level %p LEVEL on the default domain
+ * %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, LEVEL).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG(LEVEL) \
EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, LEVEL)
+/**
+ * @def EINA_CXX_LOG_CRIT()
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_CRITICAL on the default
+ * domain %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, ::EINA_LOG_LEVEL_CRITICAL).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG_CRIT() \
EINA_CXX_LOG(EINA_LOG_LEVEL_CRITICAL)
+/**
+ * @def EINA_CXX_LOG_ERR()
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_ERR on the default
+ * domain %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, ::EINA_LOG_LEVEL_ERR).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG_ERR() \
EINA_CXX_LOG(EINA_LOG_LEVEL_ERR)
+/**
+ * @def EINA_CXX_LOG_INFO()
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_INFO on the default
+ * domain %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, ::EINA_LOG_LEVEL_INFO).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG_INFO() \
EINA_CXX_LOG(EINA_LOG_LEVEL_INFO)
+/**
+ * @def EINA_CXX_LOG_DBG()
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_DBG on the default
+ * domain %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, ::EINA_LOG_LEVEL_DBG).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG_DBG() \
EINA_CXX_LOG(EINA_LOG_LEVEL_DBG)
+/**
+ * @def EINA_CXX_LOG_WARN()
+ *
+ * Logs a message with level %c EINA_LOG_LEVEL_WARN on the default
+ * domain %c EINA_LOG_DOMAIN_DEFAULT.
+ *
+ * It is a short for EINA_CXX_DOM_LOG(EINA_LOG_DOMAIN_DEFAULT, ::EINA_LOG_LEVEL_WARN).
+ *
+ * @see EINA_CXX_DOM_LOG(DOMAIN, LEVEL)
+ */
#define EINA_CXX_LOG_WARN() \
EINA_CXX_LOG(EINA_LOG_LEVEL_WARN)
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <algorithm>
#include <utility>
+/**
+ * @addtogroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
namespace efl_eina_swap_adl {
+/**
+ * @internal
+ */
template <typename T>
void swap_impl(T& lhs, T& rhs)
{
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Optional_Group Optional Value
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
+/**
+ * @internal
+ */
template <typename T>
void adl_swap(T& lhs, T& rhs)
{
::efl_eina_swap_adl::swap_impl<T>(lhs, rhs);
}
+/**
+ * This class manages an optional contained value, i.e. a value that
+ * semantically may not be present.
+ *
+ * A common use case for optional is the return value of a function that
+ * may fail. As opposed to other approaches, such as
+ * <tt>std::pair<T,bool></tt>, optional handles expensive to construct
+ * objects well and is more readable, as the intent is expressed
+ * explicitly.
+ *
+ * An optional object holding a semantically present value is considered
+ * to be @em engaged, otherwise it is considered to be @em disengaged.
+ */
template <typename T>
struct optional
{
- typedef optional<T> _self_type;
+ typedef optional<T> _self_type; /**< Type for the optional class itself. */
+ /**
+ * @brief Create a disengaged object.
+ *
+ * This constructor creates a disengaged <tt>eina::optional</tt>
+ * object, since null pointer is meant to be a valid object type.
+ */
optional(std::nullptr_t) : engaged(false)
{}
+
+ /**
+ * @brief Default constructor. Create a disengaged object.
+ */
optional() : engaged(false)
{}
+
+ /**
+ * @brief Create an engaged object by moving @p other content.
+ * @param other R-value reference to the desired type.
+ *
+ * This constructor creates an <tt>eina::optional</tt> object in an
+ * engaged state. The contained value is initialized by moving
+ * @p other.
+ */
optional(T&& other) : engaged(false)
{
_construct(std::move(other));
}
+
+ /**
+ * @brief Create an engaged object by copying @p other content.
+ * @param other Constant reference to the desired type.
+ *
+ * This constructor creates an <tt>eina::optional</tt> object in an
+ * engaged state. The contained value is initialized by copying
+ * @p other.
+ */
optional(T const& other) : engaged(false)
{
_construct(std::move(other));
}
+
+ /**
+ * @brief Copy constructor. Create an object containing the same value as @p other and in the same state.
+ * @param other Constant reference to another <tt>eina::optional</tt> object that holds the same value type.
+ *
+ * This constructor creates an <tt>eina::optional</tt> object with
+ * the same engagement state of @p other. If @p other is engaged then
+ * the contained value of the newly created object is initialized by
+ * copying the contained value of @p other.
+ */
optional(optional<T> const& other)
: engaged(false)
{
if(other.engaged) _construct(*other);
}
+
+ /**
+ * @brief Move constructor. Create an object containing the same value as @p other and in the same state.
+ * @param other R-value reference to another <tt>eina::optional</tt> object that holds the same value type.
+ *
+ * This constructor creates an <tt>eina::optional</tt> object with
+ * the same engagement state of @p other. If @p other is engaged then
+ * the contained value of the newly created object is initialized by
+ * moving the contained value of @p other.
+ */
optional(optional<T>&& other)
: engaged(false)
{
other._destroy();
}
+ /**
+ * @brief Assign new content to the object.
+ * @param other R-value reference to another <tt>eina::optional</tt> object that holds the same value type.
+ *
+ * This operator replaces the current content of the object. If
+ * @p other is engaged its contained value is moved to this object,
+ * making <tt>*this</tt> be considered engaged too. If @p other is
+ * disengaged <tt>*this</tt> is also made disengaged and its
+ * contained value, if any, is simple destroyed.
+ */
_self_type& operator=(optional<T>&& other)
{
_destroy();
other._destroy();
return *this;
}
+
+ /**
+ * @brief Assign new content to the object.
+ * @param other Constant reference to another <tt>eina::optional</tt> object that holds the same value type.
+ *
+ * This operator replaces the current content of the object. If
+ * @p other is engaged its contained value is copied to this object,
+ * making <tt>*this</tt> be considered engaged too. If @p other is
+ * disengaged <tt>*this</tt> is also made disengaged and its
+ * contained value, if any, is simple destroyed.
+ */
_self_type& operator=(optional<T>const& other)
{
optional<T> tmp(other);
return *this;
}
+ /**
+ * @brief Releases the contained value if the object is engaged.
+ */
~optional()
{
_destroy();
}
+ /**
+ * @brief Convert to @c bool based on whether the object is engaged or not.
+ * @return @c true if the object is engaged, @c false otherwise.
+ */
explicit operator bool() const
{
return is_engaged();
}
+
+ /**
+ * @brief Convert to @c bool based on whether the object is engaged or not.
+ * @return @c true if the object is disengaged, @c false otherwise.
+ */
bool operator!() const
{
bool b ( *this );
return !b;
}
+ /**
+ * @brief Access member of the contained value.
+ * @return Pointer to the contained value, whose member will be accessed.
+ */
T* operator->()
{
assert(is_engaged());
return static_cast<T*>(static_cast<void*>(&buffer));
}
+
+ /**
+ * @brief Access constant member of the contained value.
+ * @return Constant pointer to the contained value, whose member will be accessed.
+ */
T const* operator->() const
{
return const_cast<_self_type&>(*this).operator->();
}
+ /**
+ * @brief Get the contained value.
+ * @return Reference to the contained value.
+ */
T& operator*() { return get(); }
+
+ /**
+ * @brief Get the contained value.
+ * @return Constant reference to the contained value.
+ */
T const& operator*() const { return get(); }
+ /**
+ * @brief Get the contained value.
+ * @return Reference to the contained value.
+ */
T& get() { return *this->operator->(); }
+
+ /**
+ * @brief Get the contained value.
+ * @return Constant reference to the contained value.
+ */
T const& get() const { return *this->operator->(); }
+ /**
+ * @brief Swap content with another <tt>eina::optional</tt> object.
+ * @param other Another <tt>eina::optional</tt> object.
+ */
void swap(optional<T>& other)
{
if(is_engaged() && other.is_engaged())
}
}
+ /**
+ * @brief Check if the object is engaged.
+ * @return @c true if the object is currently engaged, @c false otherwise.
+ */
bool is_engaged() const
{
return engaged;
}
private:
+
+ /**
+ * @internal
+ */
template <typename U>
void _construct(U&& object)
{
new (&buffer) T(std::move(object));
engaged = true;
}
+
+ /**
+ * @internal
+ */
void _destroy()
{
if(is_engaged())
typedef typename std::aligned_storage
<sizeof(T),std::alignment_of<T>::value>::type buffer_type;
+
+ /**
+ * Member variable for holding the contained value.
+ */
buffer_type buffer;
+
+ /**
+ * Flag to tell whether the object is engaged or not.
+ */
bool engaged;
};
+/**
+ * @brief Swap content with another <tt>eina::optional</tt> object.
+ *
+ */
template <typename T>
void swap(optional<T>& lhs, optional<T>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @brief Check if both <tt>eina::optional</tt> object are equal.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return @c true if both are objects are disengaged of if both objects
+ * are engaged and contain the same value, @c false in all
+ * other cases.
+ */
template <typename T>
bool operator==(optional<T> const& lhs, optional<T> const& rhs)
{
else
return *lhs == *rhs;
}
+
+/**
+ * @brief Check if the <tt>eina::optional</tt> objects are different.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return The opposite of @ref operator==(optional<T> const& lhs, optional<T> const& rhs).
+ */
template <typename T>
bool operator!=(optional<T> const& lhs, optional<T> const& rhs)
{
return !(lhs == rhs);
}
+
+/**
+ * @brief Less than comparison between <tt>eina::optional</tt> objects.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return @c true if both objects are engaged and the contained value
+ * of @p lhs is less than the contained value of @p rhs, or if
+ * only @p lhs is disengaged. In all other cases returns
+ * @c false.
+ */
template <typename T>
bool operator<(optional<T> const& lhs, optional<T> const& rhs)
{
else
return *lhs < *rhs;
}
+
+/**
+ * @brief Less than or equal comparison between <tt>eina::optional</tt> objects.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return @c true if @p lhs is disengaged or if both objects are
+ * engaged and the contained value of @p lhs is less than or
+ * equal to the contained value of @p rhs. In all other cases
+ * returns @c false.
+ */
template <typename T>
bool operator<=(optional<T> const& lhs, optional<T> const& rhs)
{
return lhs < rhs || lhs == rhs;
}
+
+/**
+ * @brief More than comparison between <tt>eina::optional</tt> objects.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return @c true if both objects are engaged and the contained value
+ * of @p lhs is more than the contained value of @p rhs, or if
+ * only @p rhs is disengaged. In all other cases returns
+ * @c false.
+ */
template <typename T>
bool operator>(optional<T> const& lhs, optional<T> const& rhs)
{
return !(lhs <= rhs);
}
+
+/**
+ * @brief More than or equal comparison between <tt>eina::optional</tt> objects.
+ * @param lhs <tt>eina::optional</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::optional</tt> object at the right side of the expression.
+ * @return @c true if @p rhs is disengaged or if both objects are
+ * engaged and the contained value of @p lhs is more than or
+ * equal to the contained value of @p rhs. In all other
+ * cases returns @c false.
+ */
template <typename T>
bool operator>=(optional<T> const& lhs, optional<T> const& rhs)
{
return !(lhs < rhs);
}
+/**
+ * @}
+ */
+
} } // efl::eina
+/**
+ * @}
+ */
+
#endif // EINA_OPTIONAL_HH_
#include <cstdlib>
#include <cassert>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Pointer_Array_Group Array of Pointers
+ * @ingroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
+/**
+ * @internal
+ */
template <typename T>
struct _ptr_array_iterator
{
void** _ptr;
};
+/**
+ * @internal
+ */
struct _ptr_array_access_traits {
template <typename T>
{
return _ptr_array_access_traits::iend<T>(array);
}
+
+
template <typename T>
static std::size_t size(Eina_Array const* array)
{
template <typename T, typename Allocator>
class ptr_array;
+/**
+ * @ingroup Eina_Cxx_Range_Group
+ *
+ * Range for @ref ptr_array.
+ */
template <typename T>
struct range_ptr_array : _range_template<T, _ptr_array_access_traits>
{
- typedef _range_template<T, _ptr_array_access_traits> _base_type;
- typedef typename _base_type::value_type value_type;
+ typedef _range_template<T, _ptr_array_access_traits> _base_type; /**< Type for the base class. */
+ typedef typename _base_type::value_type value_type; /**< The type of each element. */
+ /**
+ * @brief Creates a range from a native Eina array handle.
+ */
range_ptr_array(Eina_Array* array)
: _base_type(array)
{}
+
+ /**
+ * @brief Creates a range from a @c ptr_array object.
+ */
template <typename Allocator>
range_ptr_array(ptr_array<value_type, Allocator>& array)
: _base_type(array.native_handle())
{}
+
+ /**
+ * @brief Get the element at the given position in the array.
+ * @param index Position of the element.
+ * @return Reference to the element at the given position.
+ */
value_type& operator[](std::size_t index) const
{
return _ptr_array_access_traits::index<T>(this->native_handle(), index);
}
};
+/**
+ * Common implementations for the ptr_array.
+ */
template <typename T, typename CloneAllocator>
struct _ptr_array_common_base
{
- typedef CloneAllocator clone_allocator_type;
+ typedef CloneAllocator clone_allocator_type; /**< Type for the clone allocator. */
+ /**
+ * @brief Creates an array with the given clone allocator.
+ */
_ptr_array_common_base(CloneAllocator clone_allocator)
: _impl(clone_allocator)
{}
+
+ /**
+ * @brief Create a new object from a handle to a native Eina_Array.
+ * @param array Handle to a native Eina_Array.
+ *
+ * This constructor wraps a pre-allocated Eina_Array providing an OOP
+ * interface to it.
+ *
+ * @warning It is important to note that the created object gains
+ * ownership of the handle, deallocating it at destruction time.
+ */
_ptr_array_common_base(Eina_Array* _array)
: _impl(_array)
{}
+
+ /**
+ * @brief Default constructor. Create an empty array.
+ *
+ * This constructor creates an array with no elements.
+ */
_ptr_array_common_base() {}
+ /**
+ * @internal
+ * @brief Get the clone allocator of the array.
+ * @return Reference to the clone allocator.
+ */
CloneAllocator& _get_clone_allocator()
{
return _impl;
}
+
+ /**
+ * @internal
+ * @brief Get the clone allocator of the array.
+ * @return Constant reference to the clone allocator.
+ *
+ * Version of @ref _get_clone_allocator() for const-qualified arrays,
+ * returns a constant reference instead.
+ */
CloneAllocator const& _get_clone_allocator() const
{
return _impl;
}
+
+ /**
+ * @internal
+ */
void _delete_clone(T const* p)
{
_get_clone_allocator().deallocate_clone(p);
}
+
+ /**
+ * @internal
+ */
T* _new_clone(T const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
+ /**
+ * @internal
+ */
struct _ptr_array_impl : CloneAllocator
{
_ptr_array_impl() : _array( ::eina_array_new(32u) ) {}
: clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {}
Eina_Array* _array;
- };
+ };
+ /**
+ * @internal
+ */
_ptr_array_impl _impl;
private:
+ /** Disabled copy constructor. */
_ptr_array_common_base(_ptr_array_common_base const& other);
+ /** Disabled assignment operator. */
_ptr_array_common_base& operator=(_ptr_array_common_base const& other);
};
+/**
+ * Array class. It provides an OOP interface to the @c Eina_Array
+ * functions, and automatically take care of allocating and deallocating
+ * resources using the RAII programming idiom.
+ *
+ * It also provides additional member functions to facilitate the access
+ * to the array content, much like a STL vector.
+ */
template <typename T, typename CloneAllocator = heap_no_copy_allocator>
class ptr_array : protected _ptr_array_common_base<T, CloneAllocator>
{
- typedef _ptr_array_common_base<T, CloneAllocator> _base_type;
+ typedef _ptr_array_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */
public:
- typedef T value_type;
- typedef T& reference;
- typedef T const& const_reference;
- typedef _ptr_array_iterator<T const> const_iterator;
- typedef _ptr_array_iterator<T> iterator;
- typedef T* pointer;
- typedef T const* const_pointer;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef CloneAllocator clone_allocator_type;
+ typedef T value_type; /**< The type of each element. */
+ typedef T& reference; /**< Type for a reference to an element. */
+ typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef _ptr_array_iterator<T const> const_iterator; /**< Type for a iterator for this container. */
+ typedef _ptr_array_iterator<T> iterator; /**< Type for a constant iterator for this container. */
+ typedef T* pointer; /**< Type for a pointer to an element. */
+ typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
+ typedef std::size_t size_type; /**< Type for size information used in the array. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
+ typedef CloneAllocator clone_allocator_type; /** Type for the clone allocator. */
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
+ /**
+ * @brief Default constructor. Create an empty array.
+ *
+ * This constructor creates a @c ptr_array object with no elements.
+ */
ptr_array() {}
+
+ /**
+ * @brief Construct an array object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates a @c ptr_array with @p n elements, each
+ * one as a copy of @p t.
+ */
ptr_array(size_type n, const_reference t)
{
while(n--)
push_back(t);
}
+
+ /**
+ * @brief Create an array with elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @param alloc Clone allocator to be used.
+ *
+ * This constructor creates a @c ptr_array with copies of the elements
+ * between @p i and @p j in the same order.
+ *
+ * @note The ending element (pointed by @p j) is not copied.
+ */
template <typename InputIterator>
ptr_array(InputIterator i, InputIterator const& j
, clone_allocator_type const& alloc = clone_allocator_type()
++i;
}
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given @c ptr_array.
+ * @param other Another @c ptr_array of the same type.
+ *
+ * This constructor creates a @c ptr_array containing a copy of each
+ * element inside @p other in the same order.
+ */
ptr_array(ptr_array<T, CloneAllocator> const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Creates a copy of a @c ptr_array with a different clone allocator.
+ * @param other Another @c ptr_array with a different clone allocator.
+ *
+ * This constructor creates a @c ptr_array containing a copy of each
+ * element inside @p other in the same order, even if the given array
+ * uses a different clone allocator.
+ */
template <typename CloneAllocator1>
ptr_array(ptr_array<T, CloneAllocator1>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Destructor. Release all allocated elements.
+ */
~ptr_array()
{
clear();
}
+
+ /**
+ * @brief Replace the current content with the content of another array.
+ * @param other Another @c ptr_array of the same type.
+ *
+ * This assignment operator replaces the content of the array by a
+ * copy of the content of @p other. The array size is adjusted
+ * accordingly and the newly copied elements keep their original order.
+ */
ptr_array<T, CloneAllocator>& operator=(ptr_array<T, CloneAllocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
-
+
+ /**
+ * @brief Remove all the elements of the array.
+ */
void clear()
{
for(iterator first = begin(), last = end(); first != last; ++first)
this->_delete_clone(&*first);
eina_array_flush(this->_impl._array);
}
+
+ /**
+ * @brief Get the current size of the array.
+ * @return Number of elements in the array.
+ *
+ * This member function returns the current number of elements inside
+ * the array.
+ */
std::size_t size() const
{
return eina_array_count(this->_impl._array);
}
+
+ /**
+ * @brief Check if the array is empty.
+ * @return @c true if the array is empty, @c false otherwise.
+ *
+ * This member function returns @c true if the array does not contain
+ * any elements, otherwise it returns @c false.
+ */
bool empty() const
{
return size() == 0u;
}
+
+ /**
+ * @brief Get the clone allocator of the array.
+ * @return Reference to the clone allocator.
+ */
clone_allocator_type get_clone_allocator() const
{
return clone_allocator_type(this->_get_clone_allocator());
}
+
+ /**
+ * @brief Add a copy of the given element at the end of the array.
+ * @param a Element to be added at the end of the array.
+ *
+ * This member function allocates a new element, as a copy of @p a,
+ * and inserts it at the end of the array.
+ */
void push_back(const_reference a)
{
push_back(this->_new_clone(a));
}
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the end of the array.
+ * @param p Pointer to a pre-allocated element to be inserted at the end of the array.
+ *
+ * This member function adds the object pointed by @p p as a element
+ * at the end of the array. The array gains ownership of the pointer
+ * and nothing is copied.
+ *
+ * @warning The array gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
void push_back(pointer p)
{
std::unique_ptr<value_type> p1(p);
push_back(p1);
}
+
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the end of the array.
+ * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the end of the array.
+ *
+ * This member function adds the object pointed by the given
+ * @c unique_ptr as a element at the end of the array. The object
+ * ownership is transferred to the array and nothing is copied.
+ *
+ * @warning The array gains ownership of the object managed by the
+ * given @c unique_ptr and will release it upon element destruction.
+ */
void push_back(std::unique_ptr<T>& p)
{
if(eina_array_push(this->_impl._array, p.get()))
else
throw std::bad_alloc();
}
+
+ /**
+ * @brief Remove the last element of the array.
+ */
void pop_back()
{
eina_array_pop(this->_impl._array);
}
+
+ /**
+ * @brief Insert a copy of the given element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param t Value to be copied to the new element.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function inserts a copy of the element @p t at the
+ * position @p i. The new element comes right before the element
+ * originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ */
iterator insert(iterator i, value_type const& t)
{
return insert(i, this->_new_clone(t));
- }
+ }
+
+ /**
+ * @brief Insert the object pointed by @p pv as a element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param pv Pointer to a pre-allocated object to be inserted to the array.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function adds the object pointed by @p pv as a element
+ * at the given position. The new element comes right before the
+ * element originally pointed by @p i. The array gains ownership of
+ * the pointer and nothing is copied.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ *
+ * @warning The array gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
iterator insert(iterator i, pointer pv)
{
std::unique_ptr<value_type> p(pv);
return insert(i, p);
}
+
+ /**
+ * @brief Insert the object pointed by @p p as a element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param p Reference to a @c unique_ptr pointing to the element to be inserted in the array.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function adds the object pointed by @p p as a element
+ * at the given position. The new element comes right before the
+ * element originally pointed by @p i. The object ownership is
+ * transferred to the array and nothing is copied.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ *
+ * @warning The array gains ownership of the object managed by the
+ * given @c unique_ptr and will release it upon element destruction.
+ */
iterator insert(iterator i, std::unique_ptr<value_type>& p)
{
std::size_t j
}
else
throw std::bad_alloc();
- }
+ }
+
+ /**
+ * @brief Insert @p n copies of @p t at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param t Value to be copied to each new inserted element.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts @p n new elements at position @p i
+ * in the array, each one as a copy of @p t. The new elements come
+ * right before the element originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
insert(i, t);
return r;
}
+
+ /**
+ * @brief Insert the object pointed by @p p and <tt>n-1</tt> copies of it as elements at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param p Pointer to a pre-allocated object to be inserted in the array.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts the object pointed by @p p and
+ * <tt>n-1</tt> copies of it as elements at the given position. The
+ * new elements come right before the element originally pointed by
+ * @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ *
+ * @warning The array gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
iterator insert(iterator i, size_t n, pointer p)
{
iterator r = i;
insert(i, this->_new_clone(p));
return r;
}
+
+ /**
+ * @brief Insert the elements between the given range at the given position.
+ * @param p Iterator pointing to the position where the new elements will be inserted.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts a copy of the elements between @p i
+ * and @p j at the position @p p. The new elements come right before
+ * the element originally pointed by @p p. Note that the element
+ * pointed by @p j is not copied.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
}
return iterator(this->_impl._array->data + index);
}
+
+ /**
+ * @brief Remove the element at the given position.
+ * @param q Iterator pointing to the element to be removed.
+ * @return Iterator pointing to the element after the removed one.
+ *
+ * This member function removes the element pointed by the iterator
+ * @p q, reducing the array size by one. At the end, a valid iterator
+ * pointing to the element right after the removed one is returned.
+ */
iterator erase(iterator q)
{
size_type size = this->size()
eina_array_pop(this->_impl._array);
return q;
}
+
+ /**
+ * @brief Remove the elements between the given range.
+ * @param i Iterator pointing to the starting position to be removed.
+ * @param j Iterator pointing to the ending position to be removed.
+ * The element pointed by this iterator is not removed.
+ * @return Iterator pointing to the new position of the first
+ * non-removed element after the removed ones (i.e. the one
+ * originally pointed by @p j).
+ *
+ * This member function removes the elements between the iterators
+ * @p i and @p j, including the element pointed by @p i but not the
+ * element pointed by @j.
+ */
iterator erase(iterator i, iterator j)
{
size_type size = this->size()
eina_array_pop(this->_impl._array);
return i;
}
+
+ /**
+ * @brief Replace the content of the array by the elements in the given range.
+ * @param i Iterator pointing to the beginning of the elements to be copied.
+ * @param j Iterator pointing to the end of the elements to be copied.
+ * Note that the element pointed by j will NOT be copied.
+ *
+ * This member function replaces the current elements by copies of the
+ * elements between the iterators @p i and @p j, including the element
+ * pointed by @p i but not the one pointed by @p j. The size of the
+ * array is adjusted accordingly and the newly copied elements remain
+ * in their original order.
+ */
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
clear();
insert(end(), i, j);
}
+
+ /**
+ * @brief Replace the content of the array by @p n copies @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ */
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element in the array.
+ */
value_type& back()
{
return _ptr_array_access_traits::back<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element in the array.
+ *
+ * Version of @ref back() for const-qualified objects. Returns a
+ * constant reference instead.
+ */
value_type const& back() const
{
return _ptr_array_access_traits::back<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the array.
+ */
value_type& front()
{
return _ptr_array_access_traits::front<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the array.
+ *
+ * Version of @ref front() for const-qualified objects. Returns a
+ * constant reference instead.
+ */
value_type const& front() const
{
return _ptr_array_access_traits::front<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reference to the element at the given position.
+ * @param index Position of the element in the array.
+ * @return Constant reference to element at position @p index.
+ *
+ * Version of @ref operator[](size_type index) for const-qualified
+ * objects. Returns a constant reference instead.
+ */
const_reference operator[](size_type index) const
{
return _ptr_array_access_traits::index<T>(this->_impl._array, index);
}
+
+ /**
+ * @brief Get a reference to the element at the given position.
+ * @param index Position of the element in the array.
+ * @return Reference to element at position @p index.
+ */
reference operator[](size_type index)
{
return _ptr_array_access_traits::index<T>(this->_impl._array, index);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * Version of @ref begin() for const-qualified objects. Returns a
+ * constant iterator instead.
+ */
const_iterator begin() const
{
return _ptr_array_access_traits::begin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * Version of @ref end() for const-qualified objects. Returns a
+ * constant iterator instead.
+ */
const_iterator end() const
{
return _ptr_array_access_traits::end<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the array.
+ * @return Iterator to the initial position of the array.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the array. If the array is empty the returned iterator
+ * is the same as the one returned by @ref end().
+ */
iterator begin()
{
return _ptr_array_access_traits::begin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the array.
+ * @return Iterator to the final position of the array.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the array. If the array is empty the returned
+ * iterator is the same as the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end()
{
return _ptr_array_access_traits::end<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * Version of @ref rbegin() for const-qualified objects. Returns a
+ * constant reverse iterator instead.
+ */
const_reverse_iterator rbegin() const
{
return _ptr_array_access_traits::rbegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * Version of @ref rend() for const-qualified objects. Returns a
+ * constant reverse iterator instead.
+ */
const_reverse_iterator rend() const
{
return _ptr_array_access_traits::rend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the array.
+ * @return Reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the array. If the array is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin()
{
return _ptr_array_access_traits::rbegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the array.
+ * @return Reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the array. If the array is
+ * empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend()
{
return _ptr_array_access_traits::rend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the array.
+ * @return Constant iterator to the initial position of the array.
+ *
+ * This member function works like @ref begin() const but is granted
+ * to return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
const_iterator cbegin() const
{
return _ptr_array_access_traits::cbegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the array.
+ * @return Constant iterator to the final position of the array.
+ *
+ * This member function works like @ref end() const but is granted to
+ * return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
const_iterator cend() const
{
return _ptr_array_access_traits::cend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the array.
+ * @return Constant reverse iterator pointing to the reverse begin of the array.
+ *
+ * This member function works like @ref rbegin() const but is granted
+ * to return a constant reverse iterator even for arrays that are not
+ * const-qualified.
+ */
const_reverse_iterator crbegin() const
{
return _ptr_array_access_traits::crbegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the array.
+ * @return Constant reverse iterator pointing to the reverse end of the array.
+ *
+ * This member function works like @ref rend() const but is granted to
+ * return a constant reverse iterator even for arrays that are not
+ * const-qualified.
+ */
const_reverse_iterator crend() const
{
return _ptr_array_access_traits::crend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> pointing to the first element of the array.
+ * @return <tt>eina::iterator</tt> to the initial position of the array.
+ *
+ * This member function returns an <tt>eina::iterator</tt> pointing to
+ * the first element of the array. If the array is empty the returned
+ * iterator is the same as the one returned by @ref iend().
+ */
eina::iterator<T> ibegin()
{
return _ptr_array_access_traits::ibegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> to the position following the last element of the array.
+ * @return <tt>eina::iterator</tt> to the final position of the array.
+ *
+ * This member function returns an <tt>eina::iterator</tt> to the
+ * position following the last element in the array. If the array is
+ * empty the returned iterator is the same as the one returned by
+ * @ref ibegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
eina::iterator<T> iend()
{
return _ptr_array_access_traits::iend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get a constant <tt>eina::iterator</tt> pointing to the first element of the array.
+ * @return Constant <tt>eina::iterator</tt> to the initial position of the array.
+ *
+ * Version of @ref ibegin() for const-qualified objects. Returns a
+ * constant <tt>eina::iterator</tt> instead.
+ */
eina::iterator<T const> ibegin() const
{
return _ptr_array_access_traits::ibegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an constant <tt>eina::iterator</tt> to the position following the last element of the array.
+ * @return Constant <tt>eina::iterator</tt> to the final position of the array.
+ *
+ * Version of @ref iend() for const-qualified objects. Returns a
+ * constant <tt>eina::iterator</tt> instead.
+ */
eina::iterator<T const> iend() const
{
return _ptr_array_access_traits::iend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> pointing to the first element of the array.
+ * @return <tt>eina::iterator</tt> to the initial position of the array.
+ *
+ * This member function works like @ref ibegin() const but is granted
+ * to return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
eina::iterator<T const> cibegin() const
{
return _ptr_array_access_traits::cibegin<T>(this->_impl._array);
}
+
+ /**
+ * @brief Get an constant <tt>eina::iterator</tt> to the position following the last element of the array.
+ * @return Constant <tt>eina::iterator</tt> to the final position of the array.
+ *
+ * This member function works like @ref iend() const but is granted to
+ * return a constant iterator even for arrays that are not
+ * const-qualified.
+ */
eina::iterator<T const> ciend() const
{
return _ptr_array_access_traits::ciend<T>(this->_impl._array);
}
+
+ /**
+ * @brief Swap content between two arrays.
+ * @param other Other @c ptr_array of the same type.
+ */
void swap(ptr_array<T, CloneAllocator>& other)
{
std::swap(this->_impl._array, other._impl._array);
}
+
+ /**
+ * @brief Get the maximum number of elements @c ptr_array can hold.
+ * @return Maximum number of elements a @c ptr_array can hold.
+ */
size_type max_size() const { return -1; }
+ /**
+ * @brief Get a handle for the wrapped Eina_Array.
+ * @return Handle for the native Eina array.
+ *
+ * This member function returns the native Eina_Array handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically release upon object destruction.
+ */
Eina_Array* native_handle()
{
return this->_impl._array;
}
+
+ /**
+ * @brief Get a constant handle for the wrapped Eina_Array.
+ * @return Constant handle for the native Eina array.
+ *
+ * Version of @ref native_handle() for const-qualified objects.
+ * Returns a constant handle instead.
+ *
+ * @see native_handle()
+ */
Eina_Array const* native_handle() const
{
return this->_impl._array;
}
};
+/**
+ * @brief Check if both arrays are equal.
+ * @param lhs @c ptr_array at the left side of the expression.
+ * @param rhs @c ptr_array at the right side of the expression.
+ * @return @c true if the arrays are equals, @c false otherwise.
+ *
+ * This operator checks if the given arrays are equal. To be considered
+ * equal both arrays need to have the same number of elements, and each
+ * element in one array must be equal to the element at the same
+ * position in the other array.
+ */
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator==(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
{
&& std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
+/**
+ * @brief Check if two arrays are different.
+ * @param lhs @c ptr_array at the left side of the expression.
+ * @param rhs @c ptr_array at the right side of the expression.
+ * @return @c true if the arrays are not equal , @c false otherwise.
+ *
+ * This operator returns the opposite of
+ * @ref operator==(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs).
+ */
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator!=(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Swap content between two arrays.
+ * @param other Other @c ptr_array of the same type.
+ */
template <typename T, typename CloneAllocator>
void swap(ptr_array<T, CloneAllocator>& lhs, ptr_array<T, CloneAllocator>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <memory>
#include <iterator>
+/**
+ * @addtogroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Pointer_List_Group List of Pointers
+ * @ingroup Eina_Cxx_Containers_Group
+ *
+ * @{
+ */
+
+/**
+ * @internal
+ */
struct _ptr_list_iterator_base
{
typedef std::ptrdiff_t difference_type;
Eina_List *_list, *_node;
};
+/**
+ * @internal
+ */
template <typename T>
struct _ptr_list_iterator : _ptr_list_iterator_base
{
}
};
+/**
+ * @internal
+ */
struct _ptr_list_access_traits {
template <typename T>
};
+/**
+ * @internal
+ */
template <typename T>
struct _const_range_ptr_list
{
native_handle_type _list;
};
+/**
+ * @internal
+ */
template <typename T>
void swap(_const_range_ptr_list<T>& lhs, _const_range_ptr_list<T>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @internal
+ */
template <typename T>
struct _mutable_range_ptr_list : _const_range_ptr_list<T>
{
native_handle_type native_handle() const
{
- return const_cast<native_handle_type>(_base_type::native_handle());
+ return const_cast<native_handle_type>(_base_type::native_handle());
}
value_type& back() const
{
template <typename T, typename Allocator>
class ptr_list;
+/**
+ * @ingroup Eina_Cxx_Range_Group
+ *
+ * Range class for @ref ptr_list.
+ */
template <typename T>
struct range_ptr_list : _range_template<T, _ptr_list_access_traits>
{
- typedef _range_template<T, _ptr_list_access_traits> _base_type;
- typedef typename _base_type::value_type value_type;
- typedef typename _base_type::native_handle_type native_handle_type;
+ typedef _range_template<T, _ptr_list_access_traits> _base_type; /**< Type for the base class. */
+ typedef typename _base_type::value_type value_type; /**< The type of each element. */
+ typedef typename _base_type::native_handle_type native_handle_type; /** Type for the native Eina list handle. */
+ /**
+ * @brief Creates a range from a native Eina list handle.
+ */
range_ptr_list(native_handle_type list)
: _base_type(list)
{}
+
+ /**
+ * @brief Creates a range from a @c ptr_list object.
+ */
template <typename Allocator>
range_ptr_list(ptr_list<value_type, Allocator>& list)
: _base_type(list.native_handle())
{}
};
+/**
+ * Common implementations for @c ptr_list.
+ */
template <typename T, typename CloneAllocator>
struct _ptr_list_common_base
{
- typedef CloneAllocator clone_allocator_type;
+ typedef CloneAllocator clone_allocator_type; /**< Type for the clone allocator. */
+ /**
+ * @brief Creates an list with the given clone allocator.
+ */
_ptr_list_common_base(CloneAllocator clone_allocator)
: _impl(clone_allocator)
{}
+
+ /**
+ * @brief Create a new object from a handle to a native Eina_List.
+ * @param _list Handle to a native Eina_List.
+ *
+ * This constructor wraps a pre-allocated Eina_List providing an OOP
+ * interface to it.
+ *
+ * @warning It is important to note that the created object gains
+ * ownership of the handle, deallocating it at destruction time.
+ */
_ptr_list_common_base(Eina_List* _list)
: _impl(_list)
{}
+
+ /**
+ * @brief Default constructor. Create an empty list.
+ *
+ * This constructor creates a list with no elements.
+ */
_ptr_list_common_base() {}
+ /**
+ * @internal
+ */
CloneAllocator& _get_clone_allocator()
{
return _impl;
}
+
+ /**
+ * @internal
+ */
CloneAllocator const& _get_clone_allocator() const
{
return _impl;
}
+
+ /**
+ * @internal
+ */
void _delete_clone(T const* p)
{
_get_clone_allocator().deallocate_clone(p);
}
+
+ /**
+ * @internal
+ */
T* _new_clone(T const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
+ /**
+ * @internal
+ */
struct _ptr_list_impl : CloneAllocator
{
_ptr_list_impl() : _list(0) {}
: clone_allocator_type(allocator), _list(0) {}
Eina_List* _list;
- };
+ };
+ /**
+ * @internal
+ */
_ptr_list_impl _impl;
private:
+ /** Disabled copy constructor. */
_ptr_list_common_base(_ptr_list_common_base const& other);
+ /** Disabled assignment operator. */
_ptr_list_common_base& operator=(_ptr_list_common_base const& other);
};
+/**
+ * List class. It provides an OOP interface to the @c Eina_List
+ * functions, and automatically take care of allocating and deallocating
+ * resources using the RAII programming idiom.
+ *
+ * It also provides additional member functions to facilitate the access
+ * to the list content, much like a STL list.
+ */
template <typename T, typename CloneAllocator = heap_no_copy_allocator>
class ptr_list : protected _ptr_list_common_base<T, CloneAllocator>
{
- typedef _ptr_list_common_base<T, CloneAllocator> _base_type;
+ typedef _ptr_list_common_base<T, CloneAllocator> _base_type; /**< Type for the base class. */
public:
- typedef T value_type;
- typedef T& reference;
- typedef T const& const_reference;
- typedef _ptr_list_iterator<T const> const_iterator;
- typedef _ptr_list_iterator<T> iterator;
- typedef T* pointer;
- typedef T const* const_pointer;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef CloneAllocator clone_allocator_type;
+ typedef T value_type; /**< The type of each element. */
+ typedef T& reference; /**< Type for a reference to an element. */
+ typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef _ptr_list_iterator<T const> const_iterator; /**< Type for a iterator for this container. */
+ typedef _ptr_list_iterator<T> iterator; /**< Type for a constant iterator for this container. */
+ typedef T* pointer; /**< Type for a pointer to an element. */
+ typedef T const* const_pointer; /**< Type for a constant pointer for an element. */
+ typedef std::size_t size_type; /**< Type for size information. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
+ typedef CloneAllocator clone_allocator_type; /** Type for the clone allocator. */
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator for this container. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for reverse iterator for this container. */
+ /**
+ * @brief Default constructor. Create an empty list.
+ *
+ * This constructor creates a @c ptr_list object with no elements.
+ */
ptr_list() {}
+
+ /**
+ * @brief Construct an list object with @p n copies of @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ *
+ * This constructor creates an @c ptr_list with @p n elements, each
+ * one as a copy of @p t.
+ */
ptr_list(size_type n, const_reference t)
{
while(n--)
push_back(t);
}
+
+ /**
+ * @brief Create a list with elements from the given range.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @param alloc Clone allocator to be used.
+ *
+ * This constructor creates a @c ptr_list with copies of the elements
+ * between @p i and @p j in the same order.
+ *
+ * @note The ending element (pointed by @p j) is not copied.
+ */
template <typename InputIterator>
ptr_list(InputIterator i, InputIterator const& j
, clone_allocator_type const& alloc = clone_allocator_type()
++i;
}
}
+
+ /**
+ * @brief Copy constructor. Creates a copy of the given @c ptr_list.
+ * @param other Another @c ptr_list of the same type.
+ *
+ * This constructor creates a @c ptr_list containing a copy of each
+ * element inside @p other in the same order.
+ */
ptr_list(ptr_list<T, CloneAllocator> const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Creates a copy of a @c ptr_list with a different clone allocator.
+ * @param other Another @c ptr_list with a different clone allocator.
+ *
+ * This constructor creates a @c ptr_list containing a copy of each
+ * element inside @p other in the same order, even if the given list
+ * uses a different clone allocator.
+ */
template <typename CloneAllocator1>
ptr_list(ptr_list<T, CloneAllocator1>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
+
+ /**
+ * @brief Destructor. Release all allocated elements.
+ */
~ptr_list()
{
clear();
}
+
+ /**
+ * @brief Replace the current content with the cotent of another list.
+ * @param other Another @c ptr_list of the same type.
+ *
+ * This assignment operator replaces the content of the list by a copy
+ * of the content of @p other. The list size is adjusted accordingly
+ * and the newly copied elements keep their original order.
+ */
ptr_list<T, CloneAllocator>& operator=(ptr_list<T, CloneAllocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
-
+
+ /**
+ * @brief Remove all the elements of the list.
+ */
void clear()
{
for(iterator first = begin(), last = end(); first != last; ++first)
eina_list_free(this->_impl._list);
this->_impl._list = 0;
}
+
+ /**
+ * @brief Get the current size of the list.
+ * @return Number of elements in the list.
+ *
+ * This member function returns the current number of elements inside
+ * the list.
+ */
std::size_t size() const
{
return _ptr_list_access_traits::size<T>(this->_impl._list);
}
+
+ /**
+ * @brief Check if the list is empty.
+ * @return @c true if the list is empty, @c false otherwise.
+ *
+ * This member function returns @c true if the list does not contain
+ * any elements, otherwise it returns @c false.
+ */
bool empty() const
{
return _ptr_list_access_traits::empty<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get the clone allocator of the list.
+ * @return Reference to the clone allocator.
+ */
clone_allocator_type get_clone_allocator() const
{
return clone_allocator_type(this->_get_clone_allocator());
}
+
+ /**
+ * @brief Add a copy of the given element at the end of the list.
+ * @param a Element to be added at the end of the list.
+ *
+ * This member function allocates a new element, as a copy of @p a,
+ * and inserts it at the end of the list.
+ */
void push_back(const_reference a)
{
push_back(this->_new_clone(a));
}
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the end of the list.
+ * @param p Pointer to a pre-allocated element to be inserted at the end of the list.
+ *
+ * This member function adds the object pointed by @p p as a element
+ * at the end of the list. The list gains ownership of the pointer and
+ * nothing is copied.
+ *
+ * @warning The list gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
void push_back(pointer p)
{
std::unique_ptr<value_type> p1(p);
push_back(p1);
}
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the end of the list.
+ * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the end of the list.
+ *
+ * This member function adds the object pointed by the given
+ * @c unique_ptr as a element at the end of the list. The object
+ * ownership is transfered to the list and nothing is copied.
+ *
+ * @warning The list gains ownership of the object managed by the
+ * given @c unique_ptr and will release it upon element destruction.
+ */
void push_back(std::unique_ptr<T>& p)
{
Eina_List* new_list = eina_list_append(this->_impl._list, p.get());
else
throw std::bad_alloc();
}
+
+ /**
+ * @brief Add a copy of the given element at the beginning of the list.
+ * @param a Element to be added at the beginning of the list.
+ *
+ * This member function allocates a new element, as a copy of @p a,
+ * and inserts it at the beginning of the list.
+ */
void push_front(const_reference a)
{
push_front(this->new_clone(a));
}
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the beginning of the list.
+ * @param p Pointer to a pre-allocated element to be inserted at the beginning of the list.
+ *
+ * This member function adds the object pointed by @p p as a element
+ * at the beginning of the list. The list gains ownership of the
+ * pointer and nothing is copied.
+ *
+ * @warning The list gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
void push_front(pointer p)
{
std::unique_ptr<value_type> p1(p);
push_front(p1);
}
+
+ /**
+ * @brief Add the object pointed by @p p as a element at the beginning of the list.
+ * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the beginning of the list.
+ *
+ * This member function adds the object pointed by the given
+ * @c unique_ptr as a element at the beginning of the list. The object
+ * ownership is transfered to the list and nothing is copied.
+ *
+ * @warning The list gains ownership of the object managed by the
+ * given @c unique_ptr and will release it upon element destruction.
+ */
void push_front(std::unique_ptr<T>& p)
{
Eina_List* new_list = eina_list_prepend(this->_impl._list, p.get());
else
throw std::bad_alloc();
}
+
+ /**
+ * @brief Remove the last element of the list.
+ */
void pop_back()
{
this->_impl._list = eina_list_remove_list(this->_impl._list, eina_list_last(this->_impl._list));
}
+
+ /**
+ * @brief Remove the first element of the list.
+ */
void pop_front()
{
this->_impl._list = eina_list_remove_list(this->_impl._list, this->_impl._list);
}
+
+ /**
+ * @brief Insert a copy of the given element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param t Value to be copied to the new element.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function inserts a copy of the element @p t at the
+ * position @p i. The new element comes right before the element
+ * originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ */
iterator insert(iterator i, value_type const& t)
{
return insert(i, this->_new_clone(t));
- }
+ }
+
+ /**
+ * @brief Insert the object pointed by @p pv as a element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param pv Pointer to a pre-allocated object to be inserted to the list.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function adds the object pointed by @p pv as a element
+ * at the given position. The new element comes right before the
+ * element originally pointed by @p i. The list gains ownership of
+ * the pointer and nothing is copied.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ *
+ * @warning The list gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
iterator insert(iterator i, pointer pv)
{
std::unique_ptr<value_type> p(pv);
return insert(i, p);
}
+
+ /**
+ * @brief Insert the object pointed by @p p as a element at the given position.
+ * @param i Iterator pointing to the position where the new element will be inserted.
+ * @param p Reference to a @c unique_ptr pointing to the element to be inserted in the list.
+ * @return Iterator pointing to the new element inserted.
+ *
+ * This member function adds the object pointed by @p p as a element
+ * at the given position. The new element comes right before the
+ * element originally pointed by @p i. The object ownership is
+ * transfered to the list and nothing is copied.
+ *
+ * At the end, a valid iterator pointing to the element just inserted
+ * is returned.
+ *
+ * @warning The list gains ownership of the object managed by the
+ * given @c unique_ptr and will release it upon element destruction.
+ */
iterator insert(iterator i, std::unique_ptr<value_type>& p)
{
this->_impl._list = _eina_list_prepend_relative_list
? ::eina_list_prev(i.native_handle())
: ::eina_list_last(this->_impl._list)
);
- }
+ }
+
+ /**
+ * @brief Insert @p n copies of @p t at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param t Value to be copied to each new inserted element.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts @p n new elements at position @p i
+ * in the list, each one as a copy of @p t. The new elements come
+ * right before the element originally pointed by @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
insert(i, t);
return r;
}
+
+ /**
+ * @brief Insert the object pointed by @p p and <tt>n-1</tt> copies of it as elements at the given position.
+ * @param i Iterator pointing to the position where the new elements will be inserted.
+ * @param n Number of elements to be inserted.
+ * @param p Pointer to a pre-allocated object to be inserted in the list.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts the object pointed by @p p and
+ * <tt>n-1</tt> copies of it as elements at the given position. The
+ * new elements come right before the element originally pointed by
+ * @p i.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ *
+ * @warning The list gains ownership of the given pointer and will
+ * release the pointed object upon element destruction.
+ */
iterator insert(iterator i, size_t n, pointer p)
{
iterator r = i;
insert(i, this->_new_clone(p));
return r;
}
+
+ /**
+ * @brief Insert the elements between the given range at the given position.
+ * @param p Iterator pointing to the position where the new elements will be inserted.
+ * @param i Iterator to the initial position. The element pointed by this iterator will be copied.
+ * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied.
+ * @return Iterator pointing to the first inserted element.
+ *
+ * This member function inserts a copy of the elements between @p i
+ * and @p j at the position @p p. The new elements come right before
+ * the element originally pointed by @p p. Note that the element
+ * pointed by @p j is not copied.
+ *
+ * At the end, a valid iterator pointing to the first element inserted
+ * is returned.
+ */
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
}
return r;
}
+
+ /**
+ * @brief Remove the element at the given position.
+ * @param q Iterator pointing to the element to be removed.
+ * @return Iterator pointing to the element after the removed one.
+ *
+ * This member function removes the element pointed by the iterator
+ * @p q, reducing the list size by one. At the end, a valid iterator
+ * pointing to the element right after the removed one is returned.
+ */
iterator erase(iterator q)
{
if(q.native_handle())
else
return q;
}
+
+ /**
+ * @brief Remove the elements between the given range.
+ * @param i Iterator pointing to the starting position to be removed.
+ * @param j Iterator pointing to the ending position to be removed.
+ * The element pointed by this iterator is not removed.
+ * @return Iterator pointing to the new position of the first
+ * non-removed element after the removed ones (i.e. the one
+ * originally pointed by @p j).
+ *
+ * This member function removes the elements between the iterators
+ * @p i and @p j, including the element pointed by @p i but not the
+ * element pointed by @j.
+ */
iterator erase(iterator i, iterator j)
{
while(i != j)
else
return end();
}
+
+ /**
+ * @brief Replace the content of the list by the elements in the given range.
+ * @param i Iterator pointing to the beginning of the elements to be copied.
+ * @param j Iterator pointing to the end of the elements to be copied.
+ * Note that the element pointed by j will NOT be copied.
+ *
+ * This member function replaces the current elements by copies of the
+ * elements between the iterators @p i and @p j, including the element
+ * pointed by @p i but not the one pointed by @p j. The size of the
+ * list is adjusted accordingly and the newly copied elements remain
+ * in their original order.
+ */
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
clear();
insert(end(), i, j);
}
+
+ /**
+ * @brief Replace the content of the list by @p n copies @p t.
+ * @param n Number of elements.
+ * @param t Value to be copied to each element.
+ */
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element in the list.
+ */
value_type& back()
{
return _ptr_list_access_traits::back<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element in the list.
+ *
+ * Version of @ref back() for const-qualified objects. Returns a
+ * constant reference instead.
+ */
value_type const& back() const
{
return _ptr_list_access_traits::back<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the list.
+ */
value_type& front()
{
return _ptr_list_access_traits::front<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the list.
+ *
+ * Version of @ref front() for const-qualified objects. Returns a
+ * constant reference instead.
+ */
value_type const& front() const
{
return _ptr_list_access_traits::front<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the list.
+ * @return Constant iterator to the initial position of the list.
+ *
+ * Version of @ref begin() for const-qualified objects. Returns a
+ * constant iterator instead.
+ */
const_iterator begin() const
{
return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the list.
+ * @return Constant iterator to the final position of the list.
+ *
+ * Version of @ref end() for const-qualified objects. Returns a
+ * constant iterator instead.
+ */
const_iterator end() const
{
return _ptr_list_access_traits::cend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the list.
+ * @return Iterator to the initial position of the list.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the list. If the list is empty the returned iterator
+ * is the same as the one returned by @ref end().
+ */
iterator begin()
{
return _ptr_list_access_traits::begin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the list.
+ * @return Iterator to the final position of the list.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the list. If the list is empty the returned
+ * iterator is the same as the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end()
{
return _ptr_list_access_traits::end<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the list.
+ * @return Constant reverse iterator pointing to the reverse begin of the list.
+ *
+ * Version of @ref rbegin() for const-qualified objects. Returns a
+ * constant reverse iterator instead.
+ */
const_reverse_iterator rbegin() const
{
return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the list.
+ * @return Constant reverse iterator pointing to the reverse end of the list.
+ *
+ * Version of @ref rend() for const-qualified objects. Returns a
+ * constant reverse iterator instead.
+ */
const_reverse_iterator rend() const
{
return _ptr_list_access_traits::rend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the list.
+ * @return Reverse iterator pointing to the reverse begin of the list.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the list. If the list is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin()
{
return _ptr_list_access_traits::rbegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the list.
+ * @return Reverse iterator pointing to the reverse end of the list.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the list. If the list is
+ * empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend()
{
return _ptr_list_access_traits::rend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the list.
+ * @return Constant iterator to the initial position of the list.
+ *
+ * This member function works like @ref begin() const but is granted
+ * to return a constant iterator even for lists that are not
+ * const-qualified.
+ */
const_iterator cbegin() const
{
return _ptr_list_access_traits::cbegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the list.
+ * @return Constant iterator to the final position of the list.
+ *
+ * This member function works like @ref end() const but is granted to
+ * return a constant iterator even for lists that are not
+ * const-qualified.
+ */
const_iterator cend() const
{
return _ptr_list_access_traits::cend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the list.
+ * @return Constant reverse iterator pointing to the reverse begin of the list.
+ *
+ * This member function works like @ref rbegin() const but is granted
+ * to return a constant reverse iterator even for lists that are not
+ * const-qualified.
+ */
const_reverse_iterator crbegin() const
{
return _ptr_list_access_traits::crbegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the list.
+ * @return Constant reverse iterator pointing to the reverse end of the list.
+ *
+ * This member function works like @ref rend() const but is granted to
+ * return a constant reverse iterator even for lists that are not
+ * const-qualified.
+ */
const_reverse_iterator crend() const
{
return _ptr_list_access_traits::crend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> pointing to the first element of the list.
+ * @return <tt>eina::iterator</tt> to the initial position of the list.
+ *
+ * This member function returns an <tt>eina::iterator</tt> pointing to
+ * the first element of the list. If the list is empty the returned
+ * iterator is the same as the one returned by @ref iend().
+ */
eina::iterator<T> ibegin()
{
return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> to the position following the last element of the list.
+ * @return <tt>eina::iterator</tt> to the final position of the list.
+ *
+ * This member function returns an <tt>eina::iterator</tt> to the
+ * position following the last element in the list. If the list is
+ * empty the returned iterator is the same as the one returned by
+ * @ref ibegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
eina::iterator<T> iend()
{
return _ptr_list_access_traits::iend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get a constant <tt>eina::iterator</tt> pointing to the first element of the list.
+ * @return Constant <tt>eina::iterator</tt> to the initial position of the list.
+ *
+ * Version of @ref ibegin() for const-qualified objects. Returns a
+ * constant <tt>eina::iterator</tt> instead.
+ */
eina::iterator<T const> ibegin() const
{
return _ptr_list_access_traits::ibegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an constant <tt>eina::iterator</tt> to the position following the last element of the list.
+ * @return Constant <tt>eina::iterator</tt> to the final position of the list.
+ *
+ * Version of @ref iend() for const-qualified objects. Returns a
+ * constant <tt>eina::iterator</tt> instead.
+ */
eina::iterator<T const> iend() const
{
return _ptr_list_access_traits::iend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an <tt>eina::iterator</tt> pointing to the first element of the list.
+ * @return <tt>eina::iterator</tt> to the initial position of the list.
+ *
+ * This member function works like @ref ibegin() const but is granted
+ * to return a constant iterator even for lists that are not
+ * const-qualified.
+ */
eina::iterator<T const> cibegin() const
{
return _ptr_list_access_traits::cibegin<T>(this->_impl._list);
}
+
+ /**
+ * @brief Get an constant <tt>eina::iterator</tt> to the position following the last element of the list.
+ * @return Constant <tt>eina::iterator</tt> to the final position of the list.
+ *
+ * This member function works like @ref iend() const but is granted to
+ * return a constant iterator even for lists that are not
+ * const-qualified.
+ */
eina::iterator<T const> ciend() const
{
return _ptr_list_access_traits::ciend<T>(this->_impl._list);
}
+
+ /**
+ * @brief Swap content between two lists.
+ * @param other Other @c ptr_list of the same type.
+ */
void swap(ptr_list<T, CloneAllocator>& other)
{
std::swap(this->_impl._list, other._impl._list);
}
+
+ /**
+ * @brief Get the maximum number of elements @c ptr_list can hold.
+ * @return Maximum number of elements a @c ptr_list can hold.
+ */
size_type max_size() const { return -1; }
+ /**
+ * @brief Get a handle for the wrapped @c Eina_List.
+ * @return Handle for the native Eina list.
+ *
+ * This member function returns the native Eina_List handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically released upon object destruction.
+ */
Eina_List* native_handle()
{
return this->_impl._list;
}
+
+ /**
+ * @brief Get a constant handle for the wrapped Eina_List.
+ * @return Constant handle for the native Eina list.
+ *
+ * Version of @ref native_handle() for const-qualified objects.
+ * Returns a constant handle instead.
+ *
+ * @see native_handle()
+ */
Eina_List const* native_handle() const
{
return this->_impl._list;
}
+
+ /**
+ * @brief Get a constant @ref eina::accessor for the list.
+ * @return Constant <tt>eina::accessor</tt> to the list.
+ *
+ * Version of @ref accessor() to const-qualified inline lists. Returns
+ * a const-qualified <tt>eina::accessor</tt> instead.
+ */
eina::accessor<T const> accessor() const
{
return eina::accessor<T const>(eina_list_accessor_new(this->_impl._list));
}
+
+ /**
+ * @brief Get a @ref eina::accessor for the list.
+ * @return <tt>eina::accessor</tt> to the list.
+ */
eina::accessor<T> accessor()
{
return eina::accessor<T>(eina_list_accessor_new(this->_impl._list));
}
};
+/**
+ * @brief Check if both lists are equal.
+ * @param lhs @c ptr_list at the left side of the expression.
+ * @param rhs @c ptr_list at the right side of the expression.
+ * @return @c true if the lists are equals, @c false otherwise.
+ *
+ * This operator checks if the given lists are equal. To be considered
+ * equal both lists need to have the same number of elements, and each
+ * element in one list must be equal to the element at the same
+ * position in the other list.
+ */
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator==(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
{
&& std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
+/**
+ * @brief Check if two lists are different.
+ * @param lhs @c ptr_list at the left side of the expression.
+ * @param rhs @c ptr_list at the right side of the expression.
+ * @return @c true if the lists are not equal , @c false otherwise.
+ *
+ * This operator returns the opposite of
+ * @ref operator==(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs).
+ */
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator!=(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Swap content between two lists.
+ * @param other Other @c ptr_list of the same type.
+ */
template <typename T, typename CloneAllocator>
void swap(ptr_list<T, CloneAllocator>& lhs, ptr_list<T, CloneAllocator>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#ifndef EINA_RANGE_TYPES_HH_
#define EINA_RANGE_TYPES_HH_
+/**
+ * @addtogroup Eina_Cxx_Content_Access_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Range_Group Range
+ * @ingroup Eina_Cxx_Content_Access_Group
+ *
+ * @{
+ */
+
+/**
+ * @brief Range implementation for immutable collections.
+ */
template <typename T, typename Traits>
struct _const_range_template
{
- typedef typename Traits::template const_iterator<T>::type const_iterator;
- typedef typename Traits::template iterator<T>::type iterator;
- typedef T value_type;
- typedef T& reference;
- typedef T const& const_reference;
- typedef T* pointer;
- typedef T const* const_pointer;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- typedef typename Traits::template const_native_handle<T>::type native_handle_type;
- typedef _const_range_template<T, Traits> _self_type;
+ typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */
+ typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */
+ typedef T value_type; /**< The type of each element. */
+ typedef T& reference; /**< Type for a reference to an element. */
+ typedef T const& const_reference; /**< Type for a constant reference to an element. */
+ typedef T* pointer; /**< Type for a pointer to an element. */
+ typedef T const* const_pointer; /**< Type for a constant pointer to an element. */
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
+ typedef std::size_t size_type; /**< Type for size information. */
+ typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
+ typedef typename Traits::template const_native_handle<T>::type native_handle_type; /**< Type for the native handle of the container. */
+ typedef _const_range_template<T, Traits> _self_type; /**< Type of the range itself. */
+
+ /**
+ * @brief Creates a range object wrapping the given native container handle.
+ */
_const_range_template(native_handle_type handle)
: _handle(handle) {}
+ /**
+ * @brief Get a constant handle for the native Eina container.
+ * @return Constant handle for the native Eina container.
+ */
native_handle_type native_handle() const { return _handle; }
+
+ /**
+ * @brief Get a constant reference to the last element.
+ * @return Constant reference to the last element of the range.
+ */
value_type const& back() const
{
return Traits::template back<value_type>(_handle);
}
+
+ /**
+ * @brief Get a constant reference to the first element.
+ * @return Constant reference to the first element of the range.
+ */
value_type const& front() const
{
return Traits::template front<value_type>(_handle);
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the range.
+ * @return Constant iterator to the initial position of the range.
+ *
+ * This member function returns a constant iterator pointing to the
+ * first element of the range. If the range contains no elements the
+ * returned iterator is the same as the one returned by @ref end() const.
+ */
const_iterator begin() const
{
return cbegin();
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the range.
+ * @return Constant iterator to the final position of the range.
+ *
+ * This member function returns a constant iterator to the position
+ * following the last element in the range. If the range contains no
+ * elements the returned iterator is the same as the one returned by
+ * @ref begin() const.
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
const_iterator end() const
{
return cend();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the range.
+ * @return Constant reverse iterator pointing to the reverse begin of the range.
+ *
+ * This member function works like @ref rbegin() const but is granted
+ * to return a constant reverse iterator even for a range to a mutable
+ * collection.
+ */
const_reverse_iterator crbegin() const
{
return const_reverse_iterator(Traits::template rbegin<value_type>(_handle));
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the range.
+ * @return Constant reverse iterator pointing to the reverse end of the range.
+ *
+ * This member function works like @ref rend() const but is granted to
+ * return a constant reverse iterator even for range to a mutable
+ * collection.
+ */
const_reverse_iterator crend() const
{
return const_reverse_iterator(Traits::template rend<value_type>(_handle));
}
+
+ /**
+ * @brief Get a constant iterator pointing to the first element of the range.
+ * @return Constant iterator to the initial position of the range.
+ *
+ * This member function works like @ref begin() const but is granted
+ * to return a constant iterator even for a range to a mutable
+ * collection.
+ */
const_iterator cbegin() const
{
return Traits::template cbegin<value_type>(_handle);
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last element of the range.
+ * @return Constant iterator to the final position of the range.
+ *
+ * This member function works like @ref end() const but is granted to
+ * return a constant iterator even for a range to a mutable collection.
+ */
const_iterator cend() const
{
return Traits::template cend<value_type>(_handle);
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the range.
+ * @return Constant reverse iterator pointing to the reverse begin of the range.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the last element of the range. If the range is empty the
+ * returned reverse iterator is the same as the one returned by
+ * @ref rend().
+ */
const_reverse_iterator rbegin()
{
return crbegin();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the range.
+ * @return Constant reverse iterator pointing to the reverse end of the range.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the position before the first element of the range. If the range
+ * is empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
const_reverse_iterator rend()
{
return crend();
}
+
+ /**
+ * @brief Check if the range does not contain any elements.
+ * @return @c true if there is no elements in the range, @c false otherwise.
+ *
+ * This member function returns @c true if the range does not contain
+ * any elements, otherwise it returns @c false.
+ */
bool empty() const
{
return Traits::template empty<value_type>(_handle);
}
+
+ /**
+ * @brief Get the number of elements in the range.
+ * @return Number of elements in the range.
+ *
+ * This member function returns the current number of elements in the
+ * range.
+ */
size_type size() const
{
return Traits::template size<value_type>(_handle);
}
+
+ /**
+ * @brief Swap content with another range of the same type.
+ * @param other Another range of the same type.
+ */
void swap(_self_type& other)
{
std::swap(_handle, other._handle);
}
protected:
+ /**
+ * @internal
+ */
native_handle_type _handle;
};
+/**
+ * @brief Swap content between two @ref _const_range_template.
+ * @param lhs First @c _const_range_template object.
+ * @param rhs Second @c _const_range_template object.
+ */
template <typename T, typename Traits>
void swap(_const_range_template<T, Traits>& lhs, _const_range_template<T, Traits>& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @brief Range implementation for mutable collections.
+ */
template <typename T, typename Traits>
struct _mutable_range_template : _const_range_template<T, Traits>
{
- typedef T value_type;
- typedef typename Traits::template iterator<T>::type iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef typename Traits::template native_handle<T>::type native_handle_type;
- typedef _const_range_template<T, Traits> _base_type;
+ typedef T value_type; /**< The type of each element. */
+ typedef typename Traits::template iterator<T>::type iterator; /**< Type for a iterator to the range. */
+ typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for constant reverse iterator to the range. */
+ typedef typename Traits::template native_handle<T>::type native_handle_type; /**< Type for the native handle of the container. */
+ typedef _const_range_template<T, Traits> _base_type; /**< Type for the base class. */
+ /**
+ * @brief Creates a range object wrapping the given native container handle.
+ */
_mutable_range_template(native_handle_type handle)
: _base_type(handle) {}
+ /**
+ * @brief Get a constant handle for the native Eina container.
+ * @return Constant handle for the native Eina container.
+ */
native_handle_type native_handle() const
{
return Traits::template native_handle_from_const<T>(_base_type::native_handle());
}
+
+ /**
+ * @brief Get a reference to the last element.
+ * @return Reference to the last element of the range.
+ */
value_type& back() const
{
return Traits::template back<value_type>(native_handle());
}
+
+ /**
+ * @brief Get a reference to the first element.
+ * @return Reference to the first element of the range.
+ */
value_type& front() const
{
return Traits::template front<value_type>(native_handle());
}
+
+ /**
+ * @brief Get an iterator pointing to the first element of the range.
+ * @return Iterator to the initial position of the range.
+ *
+ * This member function returns an iterator pointing to the first
+ * element of the range. If the range contains no elements the
+ * returned iterator is the same as the one returned by @ref end() const.
+ */
iterator begin() const
{
return Traits::template begin<value_type>(native_handle());
}
+
+ /**
+ * @brief Get an iterator to the position following the last element of the range.
+ * @return Iterator to the final position of the range.
+ *
+ * This member function returns an iterator to the position following
+ * the last element in the range. If the range contains no elements
+ * the returned iterator is the same as the one returned by
+ * @ref begin() const.
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
iterator end() const
{
return Traits::template end<value_type>(native_handle());
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse begin of the range.
+ * @return Reverse iterator pointing to the reverse begin of the range.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * last element of the range. If the range is empty the returned
+ * reverse iterator is the same as the one returned by @ref rend().
+ */
reverse_iterator rbegin() const
{
return Traits::template rbegin<value_type>(native_handle());
}
+
+ /**
+ * @brief Get a reverse iterator pointing to the reverse end of the range.
+ * @return Reverse iterator pointing to the reverse end of the range.
+ *
+ * This member function returns a reverse iterator pointing to the
+ * position before the first element of the range. If the range is
+ * empty the returned iterator is the same as the one returned by
+ * @ref rbegin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
reverse_iterator rend() const
{
return Traits::template rend<value_type>(native_handle());
}
protected:
+ /**
+ * @internal
+ */
using _base_type::_handle;
};
+/**
+ * Range class.
+ *
+ * Provide objects for accessing and/or modifying elements inside a
+ * container without modifying the container itself.
+ */
template <typename T, typename Traits>
struct _range_template : private std::conditional
<std::is_const<T>::value
, _const_range_template<typename std::remove_const<T>::type, Traits>
, _mutable_range_template<T, Traits> >::type
{
- typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable;
- typedef typename std::remove_const<T>::type value_type;
+ typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable; /**< Type that specifies if the elements can be modified. */
+ typedef typename std::remove_const<T>::type value_type; /**< The type of each element. */
typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits>
- , _const_range_template<value_type, Traits> >::type _base_type;
- typedef typename _base_type::native_handle_type native_handle_type;
-
- typedef value_type& reference;
- typedef value_type const& const_reference;
- typedef value_type* pointer;
- typedef value_type const* const_pointer;
- typedef typename Traits::template const_iterator<T>::type const_iterator;
- typedef typename _base_type::const_reverse_iterator const_reverse_iterator;
- typedef typename Traits::template iterator<T>::type iterator;
- typedef typename _base_type::reverse_iterator reverse_iterator;
- typedef typename _base_type::size_type size_type;
- typedef typename _base_type::difference_type difference_type;
+ , _const_range_template<value_type, Traits> >::type _base_type; /**< Type for the base class. */
+ typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
+ typedef value_type& reference; /**< Type for a reference to an element. */
+ typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
+ typedef value_type* pointer; /**< Type for a pointer to an element. */
+ typedef value_type const* const_pointer; /**< Type for a constant pointer to an element. */
+ typedef typename Traits::template const_iterator<T>::type const_iterator; /**< Type for constant iterator to the range. */
+ typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
+ typedef typename Traits::template iterator<T>::type iterator; /**< Type for iterator to the range. */
+ typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator to the range. */
+ typedef typename _base_type::size_type size_type; /**< Type for size information. */
+ typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
+
+ /**
+ * @brief Creates a range object wrapping the given native container handle.
+ */
_range_template(native_handle_type handle)
: _base_type(handle)
{}
using _base_type::_handle;
};
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <functional>
+/**
+ * @addtogroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Ref_Group Reference Wrapper
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
+/**
+ * @brief Creates a @c reference_wrapper to the given object.
+ * @return @c reference_wrapper holding a reference to the given object.
+ *
+ * Creates the appropriate reference_wrapper type to hold a reference to
+ * the given object. If the argument is itself a @c reference_wrapper,
+ * it creates a copy of it instead.
+ */
using std::ref;
+
+/**
+ * @brief Creates a @c reference_wrapper to the given object.
+ * @return @c reference_wrapper holding a reference to the given object.
+ *
+ * Specialized version of @ref ref for @c reference_wrapper to constant
+ * types.
+ */
using std::cref;
+
+/**
+ * Class that wraps a reference in a copyable, assignable object.
+ */
using std::reference_wrapper;
+/**
+ * Get a reference from a @c reference_wrapper. If @p t is already a
+ * reference just return a reference to @p t.
+ *
+ * @{
+ */
template <typename T>
T& unref(T& t)
{
return t;
}
-
+
template <typename T>
T& unref(reference_wrapper<T> t)
{
return t.get();
}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
}}
+/**
+ * @}
+ */
+
#endif
#include <cstring>
#include <stdexcept>
+/**
+ * @addtogroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Stringshare_Group Stringshare
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * C++ Binding to Eina_Stringshare.
+ *
+ * This class allows you to store a single copy of a string, and use in
+ * multiple places throughout your program.
+ *
+ * This is a method to reduce the number of duplicated strings kept in
+ * memory. It's pretty common for the same strings to be dynamically
+ * allocated repeatedly between applications and libraries, especially in
+ * circumstances where you could have multiple copies of a structure that
+ * allocates the string. So rather than duplicating and freeing these
+ * strings, you request a read-only pointer to an existing string and
+ * only incur the overhead of a hash look-up.
+ *
+ * It sounds like micro-optimizing, but profiling has shown this can have
+ * a significant impact as you scale the number of copies up. It improves
+ * string creation/destruction speed, reduces memory use and decreases
+ * memory fragmentation, so a win all-around.
+ *
+ * @{
+ */
+
+/**
+ * Type for stealing the ownership of a string that was previously shared.
+ */
struct steal_stringshare_ref_t {};
+
+/**
+ * Constant instance of @c steal_stringshare_ref_t for quick reference.
+ */
steal_stringshare_ref_t const steal_stringshare_ref = {};
+/**
+ * Stringshare class. It provides an OOP interface to the
+ * @c Eina_Stringshare functions, and automatically take care of sharing
+ * the string upon construction and deleting it upon destruction using
+ * the RAII programming idiom.
+ *
+ * It also provides additional member functions to facilitate the access
+ * to the string content, much like a STL string.
+ */
struct stringshare
{
typedef char value_type;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
+ /**
+ * @brief Default constructor. Creates a new object holding an shared empty string.
+ * @see stringshare(const char* str)
+ */
stringshare()
: _string( ::eina_stringshare_add("") )
{}
+
+ /**
+ * @brief Share an instance of the given string wrapped by the newly created @c stringshare object.
+ * @param <tt>NULL</tt>-terminated string to be shared.
+ *
+ * This constructor creates an <tt>eina::stringshare</tt> object that
+ * shares the given string and wraps the shared pointer, providing an
+ * OOP interface to the string content. If the string is already
+ * shared this constructor simple increment its reference counter and
+ * wraps the shared pointer.
+ *
+ * @see stringshare(char* str, steal_stringshare_ref_t)
+ */
stringshare(const char* str)
: _string( ::eina_stringshare_add(str) )
{
}
+
+ /**
+ * @brief Create an <tt>eina::stringshare</tt> that steal the ownership of the given shared string.
+ * @param str Shared string whose ownership should be stolen.
+ *
+ * This constructor creates an <tt>eina::stringshare</tt> object that
+ * steals the ownership of the given shared string. At destruction
+ * time, the reference counter for the shared string will be
+ * decremented.
+ *
+ * The second parameter is an empty object of a specific type that
+ * should be supplied to explicitly inform that this is the intended
+ * constructor; and to differentiate this from
+ * @ref stringshare(const char* str).
+ *
+ * @warning @p str should be a string that was previously shared (most
+ * likely by an call to the native @c eina_stringshare_add function).
+ * If the string is not shared, upon destruction time bad things will
+ * happen, likely a segmentation fault.
+ *
+ * @see stringshare(const char* str)
+ */
stringshare(char* str, steal_stringshare_ref_t)
: _string( str )
{
}
+
+ /**
+ * @brief Share the string between the iterator.
+ * @param i Iterator to the initial position of the string (inclusive).
+ * @param j Iterator to the final position of the string (exclusive).
+ * @note The ending position (pointed by @p j) is not considered.
+ * @see stringshare(const char* str)
+ */
template <typename InputIterator>
stringshare(InputIterator i, InputIterator j
, typename eina::enable_if
}
_string = ::eina_stringshare_add(tmp.c_str());
}
+
+ /**
+ * @brief Share the string between the iterator.
+ * @param i Iterator to the initial position of the string (inclusive).
+ * @param j Iterator to the final position of the string (exclusive).
+ * @note The ending position (pointed by @p j) is not considered.
+ * @see stringshare(const char* str)
+ */
template <typename ContiguousMemoryIterator>
stringshare(ContiguousMemoryIterator i, ContiguousMemoryIterator j
, typename eina::enable_if
{
}
+ /**
+ * @brief Destructor. Delete the shared string.
+ *
+ * Decreases the reference counter associated with the shared string.
+ * If the reference counter reaches 0, the memory associated with the
+ * string is freed.
+ */
~stringshare()
{
::eina_stringshare_del(_string);
}
+ /**
+ * @brief Copy constructor. Creates a new <tt>eina::stringshare</tt> associated with the same shared string.
+ * @param other Another <tt>eina::stringshare</tt>.
+ *
+ * This constructor increments the reference counter to the shared
+ * string associated with @p other.
+ *
+ * @see stringshare(const char* str)
+ */
stringshare(stringshare const& other)
: _string( eina_stringshare_ref(other._string) )
{}
+
+ /**
+ * @brief Replace the current shared string.
+ * @param other Another <tt>eina::stringshare</tt>.
+ *
+ * This operator replaces the current shared string by the string
+ * shared by @p other. The reference counter of the older shared
+ * string is decremented (the string is released if needed) and the
+ * reference counter of the given shared string is incremented.
+ */
stringshare& operator=(stringshare const& other)
{
::eina_stringshare_refplace(&_string, other._string);
return *this;
}
+
+ /**
+ * @brief Replace the current shared string.
+ * @param c_string <tt>NULL</tt>-terminated string.
+ *
+ * This operator replaces the shared string currently associated with
+ * this object by a shared instance of @p c_string.
+ *
+ * @see stringshare(const char* str)
+ */
stringshare& operator=(const char* c_string)
{
::eina_stringshare_replace(&_string, c_string);
return *this;
}
-
+
+ /**
+ * @brief Get a constant iterator pointing to the first character of the string.
+ * @return Constant iterator to the initial position of the string.
+ *
+ * This member function returns a constant iterator pointing to the
+ * first character of the string. If the string is empty the iterator
+ * is equal to the one returned by @ref end() const.
+ */
const_iterator begin() const
{
return _string;
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last character of the string.
+ * @return Constant iterator to the final position of the string.
+ *
+ * This member function returns an constant iterator to the position
+ * following the last character in the string. If the string is empty
+ * the iterator is equal to the one returned by @ref begin().
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
const_iterator end() const
{
return _string + size();
}
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
+ * @return Constant reverse iterator pointing to the reverse begin of the string.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the last character of the string. If the string is empty the
+ * returned reverse iterator is the same as the one returned by
+ * @ref rend() const.
+ */
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the string.
+ * @return Constant reverse iterator pointing to the reverse end of the string.
+ *
+ * This member function returns a constant reverse iterator pointing
+ * to the position before the first character of the string. If the
+ * string is empty the returned iterator is the same as the one
+ * returned by @ref rbegin() const.
+ *
+ * @note Note that attempting to access this position causes undefined
+ * behavior.
+ */
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
+ /**
+ * @brief Get a constant iterator pointing to the first character of the string.
+ * @return Constant iterator to the initial position of the string.
+ *
+ * This member function works just like @ref begin() const. But it is
+ * granted to always return a constant iterator.
+ */
const_iterator cbegin() const
{
return begin();
}
+
+ /**
+ * @brief Get a constant iterator to the position following the last character of the string.
+ * @return Constant iterator to the final position of the string.
+ *
+ * This member function works just like @ref end() const. But it is
+ * granted to always return a constant iterator.
+ */
const_iterator cend() const
{
return end();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse begin of the string.
+ * @return Constant reverse iterator pointing to the reverse begin of the string.
+ *
+ * This member function works just like @ref rbegin() const. But it is
+ * granted to always return a constant reverse iterator.
+ */
const_reverse_iterator crbegin() const
{
return rbegin();
}
+
+ /**
+ * @brief Get a constant reverse iterator pointing to the reverse end of the string.
+ * @return Constant reverse iterator pointing to the reverse end of the string.
+ *
+ * This member function works just like @ref rend() const. But it is
+ * granted to always return a constant reverse iterator.
+ */
const_reverse_iterator crend() const
{
return rend();
}
+ /**
+ * @brief Get the size of the string.
+ * @return Number of characters in the string.
+ */
size_type size() const
{
return eina_stringshare_strlen(_string);
}
+ /**
+ * @brief Alias to @ref size() const.
+ */
size_type length() const
{
return size();
}
+
+ /**
+ * @brief Get the maximum number of characters a string can hold.
+ * @return Maximum number of characters a string can hold.
+ */
size_type max_size() const
{
return -1;
}
+
+ /**
+ * @brief Check if the string has no characters.
+ * @return @c true if the string has no characters, @c false otherwise.
+ */
bool empty() const
{
return _string[0] == 0;
}
+
+ /**
+ * @brief Get the character at the given position.
+ * @param i Position of the character in the string.
+ * @return Constant reference to the character at the given position.
+ * @note Do not check if the given position exceeds the string size.
+ */
const_reference operator[](size_type i) const
{
return _string[i];
}
+
+ /**
+ * @brief Get the character at the given position.
+ * @param i Position of the character in the string.
+ * @return Constant reference to the character at the given position.
+ * @throw <tt>std::out_of_range</tt> if the given position exceeds the string size.
+ *
+ * This member function returns a constant reference to the character
+ * at the position @p i. If @p i exceeds the string size this function
+ * will throw a <tt>std::out_of_range</tt>.
+ */
const_reference at(size_type i) const
{
if(i < size())
else
throw std::out_of_range("");
}
+
+ /**
+ * @brief Get the last character of the string.
+ * @return Constant reference to the last character of the string.
+ */
const_reference back() const
{
return _string[size()-1];
}
+
+ /**
+ * @brief Get the first character of the string.
+ * @return Constant reference to the first character of the string.
+ */
const_reference front() const
{
return _string[0];
}
+ /**
+ * @brief Swap shared strings with other <tt>eina::stringshare</tt>.
+ */
void swap(stringshare& other)
{
std::swap(_string, other._string);
}
+ /**
+ * @brief Get the c-like shared string currently associated with the object.
+ * @return Pointer to the shared string.
+ * @note The pointer returned may be invalidated by calls to non-const member functions.
+ */
const char* c_str() const
{
- return _string;
+ return _string;
}
+
+ /**
+ * @brief Alias to @ref c_str() const.
+ */
const char* data() const
{
- return _string;
+ return _string;
}
-
+
private:
+ /**
+ * @internal
+ */
Eina_Stringshare* _string;
};
+/**
+ * Specialization of the default template to define the
+ * <tt>stringshare::const_iterator</tt> as a contiguous iterator.
+ */
template <>
struct is_contiguous_iterator<stringshare::const_iterator> : true_type {};
+/**
+ * @brief Check if two <tt>eina::stringshare</tt> objects represent the same string.
+ * @return @c true if the strings of the objects are equal, @c false otherwise.
+ *
+ * This operator checks if two <tt>eina::stringshare</tt> objects
+ * represent the same string. Because of the nature of the objects,
+ * this operation falls into a simple pointer comparison, since
+ * identical strings are represented by the same instance.
+ */
inline bool operator==(stringshare const& lhs, stringshare const& rhs)
{
return lhs.c_str() == rhs.c_str();
}
+/**
+ * @brief Check if two <tt>eina::stringshare</tt> objects represent different strings.
+ * @return @c true if the strings of the objects are different, @c false otherwise.
+ *
+ * This function essentially returns the opposite of
+ * @ref operator==(stringshare const& lhs, stringshare const& rhs).
+ */
inline bool operator!=(stringshare const& lhs, stringshare const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Compare an <tt>eina::stringshare</tt> object with a c-like string.
+ * @return @c true if the content of the <tt>eina::stringshare</tt>
+ * string is equal the content of the given string, @c false
+ * otherwise.
+ */
inline bool operator==(stringshare const& lhs, const char* rhs)
{
return lhs.c_str() == rhs || std::strcmp(lhs.c_str(), rhs) == 0;
}
+/**
+ * @brief Compare an <tt>eina::stringshare</tt> object with a c-like string.
+ * @return @c true if the content of the <tt>eina::stringshare</tt>
+ * string is different from content of the given string,
+ * @c false otherwise.
+ */
inline bool operator!=(stringshare const& lhs, const char* rhs)
{
return !(lhs == rhs);
}
+/**
+ * @brief Compare an <tt>eina::stringshare</tt> object with a c-like string.
+ * @return @c true if the content of the <tt>eina::stringshare</tt>
+ * string is equal the content of the given string, @c false
+ * otherwise.
+ */
inline bool operator==(const char* lhs, stringshare const& rhs)
{
return rhs == lhs;
}
+/**
+ * @brief Compare an <tt>eina::stringshare</tt> object with a c-like string.
+ * @return @c true if the content of the <tt>eina::stringshare</tt>
+ * string is different from content of the given string,
+ * @c false otherwise.
+ */
inline bool operator!=(const char* lhs, stringshare const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <chrono>
#include <mutex>
+/**
+ * @addtogroup Eina_Cxx_Tools_Group Tools
+ *
+ * @{
+ */
+
#define EFL_EINA_BOOST_MOVABLE_BUT_NOT_COPYABLE(x)
#define EFL_EINA_BOOST_RV_REF(x) x const&
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Mutex_Group Mutex
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
+/**
+ * Provides an OOP interface to the @c Eina_Lock and automatic resource
+ * allocation and deallocation using the RAII programming idiom.
+ *
+ * This class implements mutual exclusion variables (mutexes) in a way
+ * that strongly resembles the STL <tt>std::mutex</tt>.
+ */
struct mutex
{
- typedef Eina_Lock* native_handle_type;
+ typedef Eina_Lock* native_handle_type; /**< Type for the native Eina_Lock pointer. */
+
+ /**
+ * @brief Create a new mutex.
+ *
+ * Automatically allocates a new mutex and does any platform dependent
+ * initialization that is required.
+ */
mutex()
{
::eina_lock_new(&_mutex);
}
+
+ /**
+ * @brief Release mutex resources.
+ *
+ * Automatically deallocates the mutex and does any platform dependent
+ * cleanup that is required.
+ */
~mutex()
{
::eina_lock_free(&_mutex);
}
+
+ /**
+ * @brief Lock the mutex.
+ * @throw <tt>eina::system_error</tt> with the code
+ * <tt>eina::errc::resource_deadlock_would_occur</tt> if the
+ * operation fails because a deadlock condition exists. If some
+ * other condition causes the lock to fail (other than the
+ * mutex being already locked) the error code will be an
+ * internal Eina error code.
+ *
+ * This member function locks the mutex. If the mutex is locked
+ * already, this call will block until the lock is released. This is
+ * appropriate in many cases, but consider using @ref try_lock() if
+ * you don't need to block.
+ */
void lock()
{
::Eina_Lock_Result r = ::eina_lock_take(&_mutex);
throw system_error(get_error_code());
}
}
+
+ /**
+ * @brief Attempts to lock the mutex.
+ * @return @c true if it succeed in locking the mutex, @c false otherwise.
+ * @throw <tt>eina::system_error</tt> with the code
+ * <tt>eina::errc::resource_deadlock_would_occur</tt> if the
+ * operation fails because a deadlock condition exists. If some
+ * other condition causes the lock to fail (other than the
+ * mutex being already locked) the error code will be an
+ * internal Eina error code.
+ *
+ * This member function attempts to lock the mutex, identical to
+ * @ref lock(), but returns immediately if the mutex is already locked.
+ */
bool try_lock()
{
::Eina_Lock_Result r = ::eina_lock_take_try(&_mutex);
throw system_error(get_error_code());
}
}
+
+ /**
+ * @brief Unlock the lock.
+ * @throw <tt>eina::system_error</tt> with the code
+ * <tt>eina::errc::resource_deadlock_would_occur</tt> if the
+ * operation fails because a deadlock condition exists. If some
+ * other condition causes the lock to fail the error code will
+ * be an internal Eina error code.
+ *
+ * This member function will unlock the mutex.
+ *
+ * @note If successful, and EINA_HAVE_DEBUG_THREADS is defined, the
+ * mutex is updated and information about the locking process
+ * is removed (e.g. thread number and backtrace for POSIX).
+ */
void unlock()
{
::Eina_Lock_Result r = ::eina_lock_release(&_mutex);
throw system_error(get_error_code());
}
}
+
+ /**
+ * @brief Print debug information about the mutex.
+ *
+ * This member function prints debug information for the mutex. The
+ * information is platform dependent. On POSIX systems it will print
+ * the address of mutex, lock state, thread number and a backtrace.
+ */
void debug()
{
::eina_lock_debug(&_mutex);
}
+
+ /**
+ * @brief Get a handle for the wrapped @c Eina_Lock.
+ * @return Handle for the native @c Eina_Lock.
+ *
+ * This member function returns the native @c Eina_Lock handle that is
+ * wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically released upon object destruction.
+ */
native_handle_type native_handle()
{
return &_mutex;
}
private:
+ /** Disabled copy constructor. **/
mutex(mutex const&) = delete;
+ /** Disabled assignment operator. **/
mutex& operator=(mutex const&) = delete;
+ /**
+ * @internal
+ */
Eina_Lock _mutex;
};
+/**
+ * @brief Manage a mutex object by keeping it always locked.
+ *
+ * Inherited for the STL object <tt>std::lock_guard</tt>.
+ */
using std::lock_guard;
+
+/**
+ * @brief Manages a mutex object.
+ *
+ * Inherited for the STL object <tt>std::unique_lock</tt>. This class
+ * guarantees an unlocked status on destruction.
+ */
using std::unique_lock;
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eina_Cxx_Condition_Variable_Group Condition Variable
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
+/**
+ * Provides an OOP interface to the @c Eina_Condition and automatic
+ * resource allocation and deallocation using the RAII programming idiom.
+ *
+ * This class implements condition variables in a way that strongly
+ * resembles the STL <tt>std::condition_variable</tt>.
+ */
struct condition_variable
{
- typedef Eina_Condition* native_handle_type;
-
+ typedef Eina_Condition* native_handle_type; /**< Type for the native Eina_Lock pointer. */
+
+ /**
+ * @brief Create a new condition variable.
+ *
+ * Automatically allocates a new condition variable and does any
+ * platform dependent initialization that is required.
+ */
condition_variable()
{
::eina_condition_new(&_cond, _mutex.native_handle());
}
+
+ /**
+ * @brief Release the condition variable resources.
+ *
+ * Automatically deallocates the condition variable and does any
+ * platform dependent cleanup that is required.
+ */
~condition_variable()
{
::eina_condition_free(&_cond);
}
+ /**
+ * @brief Unblock a thread waiting for this condition.
+ * @throw <tt>eina::system_error</tt> on fail.
+ *
+ * This member function unblock a thread waiting on this condition
+ * variable. If there is more than one thread waiting on this
+ * condition, one of them will be unblocked, but which one is
+ * undefined. If you do not know for sure that there is only one
+ * thread waiting, use @ref notify_all() instead.
+ */
void notify_one()
{
eina::unique_lock<eina::mutex> l(_mutex);
if(!r)
throw eina::system_error(eina::get_error_code());
}
+
+ /**
+ * @brief Unblock all threads waiting for this condition.
+ * @throw <tt>eina::system_error</tt> on fail.
+ *
+ * This member function unblocks all the threads waiting on the this
+ * condition. If you know for sure that there is only one thread
+ * waiting, use @ref notify_one instead to gain a little optimization.
+ */
void notify_all()
{
eina::unique_lock<eina::mutex> l(_mutex);
if(!r)
throw eina::system_error(eina::get_error_code());
}
+
+ /**
+ * @brief Causes a thread to wait until notified.
+ * @param lock A lockable object (@c mutex, @c unique_lock, etc) that
+ * is currently locked by this thread. All concurrent
+ * calls to wait member functions of this object shall use
+ * the same lockable object.
+ *
+ * This member function makes a thread block until notified.
+ */
template <typename Lock>
void wait(Lock& lock)
{
::eina_condition_wait(&_cond);
lock.lock();
}
+
+ /**
+ * @brief Causes a thread to wait until notified.
+ * @param lock A lockable object (@c mutex, @c unique_lock, etc) that
+ * is currently locked by this thread. All concurrent
+ * calls to wait member functions of this object shall use
+ * the same lockable object.
+ * @param p A callable object or function that takes no arguments and
+ * returns a value that can be evaluated as a bool. This is
+ * called repeatedly until it evaluates to true.
+ *
+ * This member function only blocks the thread if @p p is evaluated to
+ * @c false. In this case the thread remains blocked until notified
+ * and the result of @p p evaluates to @c true.
+ */
template <typename Lock, typename Predicate>
void wait(Lock& lock, Predicate p)
{
while(!p())
wait(lock);
}
+
+ /**
+ * @brief Get a handle for the wrapped @c Eina_Condition.
+ * @return Handle for the native @c Eina_Condition.
+ *
+ * This member function returns the native @c Eina_Condition handle
+ * that is wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically released upon object destruction.
+ */
native_handle_type native_handle()
{
return &_cond;
}
private:
+ /** Disabled copy constructor. **/
condition_variable(condition_variable const&);
+ /** Disabled assignment operator. **/
condition_variable& operator=(condition_variable const&);
- mutex _mutex;
- Eina_Condition _cond;
+ mutex _mutex; /**< @internal */
+ Eina_Condition _cond; /**< @internal */
};
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eina_Cxx_Thread_Group Thread
+ * @ingroup Eina_Cxx_Tools_Group
+ *
+ * @{
+ */
+
+/**
+ * Thread identifier.
+ */
struct thread_id
{
+ /**
+ * @brief Creates a @c thread_id that represents all non-joinable.
+ */
thread_id() noexcept
: _raw(0u)
{
}
+
+ /**
+ * @brief
+ */
thread_id(Eina_Thread raw)
: _raw(raw) {}
+
+ /**
+ * @brief Check if two thread identifiers are the same.
+ * @return @c true if the thread identifiers have the same value.
+ */
friend inline bool operator==(thread_id lhs, thread_id rhs)
{
return lhs._raw == rhs._raw;
}
+
+ /**
+ * @brief Check if two thread identifiers are different.
+ * @return @c true if the thread identifiers have different values.
+ */
friend inline bool operator!=(thread_id lhs, thread_id rhs)
{
return lhs._raw != rhs._raw;
}
+
+ /**
+ * @brief Less than comparison of thread identifiers.
+ * @param lhs @c thread_id at the left side of the expression.
+ * @param rhs @c thread_id at the right side of the expression.
+ * @return @c true if @c lhs is less than @c rhs, @c false otherwise.
+ * @note The order established by relational operators is
+ * implementation-defined.
+ */
friend inline bool operator<(thread_id lhs, thread_id rhs)
{
return std::less<Eina_Thread>()(lhs._raw, rhs._raw);
}
private:
- Eina_Thread _raw;
-
+ Eina_Thread _raw; /**< @internal */
+
+ /**
+ * @brief Inserts a textual representation in the given stream.
+ * @param out Output stream where the textual representation will be inserted.
+ * @param id @c thread_id object.
+ * @return Reference to the modified <tt>std::basic_ostream</tt> object.
+ */
template <typename charT, typename Traits>
friend std::basic_ostream<charT, Traits>&
operator<<(std::basic_ostream<charT, Traits>& out, thread_id id)
}
};
+/**
+ * @brief Less than or equal comparison of thread identifiers.
+ * @param lhs @c thread_id at the left side of the expression.
+ * @param rhs @c thread_id at the right side of the expression.
+ * @return @c true if @c lhs is less than or equal to @c rhs, @c false otherwise.
+ * @note The order established by relational operators is
+ * implementation-defined.
+ */
inline bool operator<=(thread_id lhs, thread_id rhs)
{
return (lhs == rhs) || lhs < rhs;
}
+
+/**
+ * @brief More than comparison of thread identifiers.
+ * @param lhs @c thread_id at the left side of the expression.
+ * @param rhs @c thread_id at the right side of the expression.
+ * @return @c true if @c lhs is more than @c rhs, @c false otherwise.
+ * @note The order established by relational operators is
+ * implementation-defined.
+ */
inline bool operator>(thread_id lhs, thread_id rhs)
{
return !(lhs <= rhs);
}
+
+/**
+ * @brief More than or equal comparison of thread identifiers.
+ * @param lhs @c thread_id at the left side of the expression.
+ * @param rhs @c thread_id at the right side of the expression.
+ * @return @c true if @c lhs is more than or equal to @c rhs, @c false otherwise.
+ * @note The order established by relational operators is
+ * implementation-defined.
+ */
inline bool operator>=(thread_id lhs, thread_id rhs)
{
return !(lhs < rhs);
}
+/**
+ * @internal
+ */
namespace _detail {
+/**
+ * @internal
+ */
struct arguments
{
Eina_Lock mutex;
std::function<void()> function;
};
+/**
+ * @internal
+ */
inline void* create_thread(void* data, Eina_Thread)
{
arguments* args = static_cast<arguments*>(data);
}
+/**
+ * Provides an OOP interface to the @c Eina_Thread and automatic
+ * resource allocation and deallocation using the RAII programming idiom.
+ *
+ * This class implements threads in a way that strongly resembles the
+ * STL <tt>std::thread</tt>.
+ */
struct thread
{
- typedef thread_id id;
- typedef Eina_Thread native_handle_type;
+ typedef thread_id id; /**< Type for the thread identifier. */
+ typedef Eina_Thread native_handle_type; /**< Type for the native Eina_Thread handle. */
+ /**
+ * @brief Creates a thread object that does not represent any thread of execution.
+ */
thread() noexcept
: _joinable(false), _raw(0u)
{
}
+ /**
+ * @brief Creates a thread of execution.
+ * @param f Pointer to function or callable object to execute in the new thread.
+ * The return value (if any) is ignored.
+ * @param args Arguments to pass to the @p f.
+ *
+ * This constructor creates a thread object that represents a thread
+ * of execution. The new thread of execution calls @p f passing
+ * @p args as arguments (all arguments are copied/moved to
+ * thread-accessible storage).
+ *
+ * Any exceptions thrown during evaluation and copying/moving of the
+ * arguments are thrown in the current thread, not the new thread.
+ */
template <typename F, class ... Args>
explicit thread(F&& f, Args&&... args)
{
_detail::arguments arguments;
arguments.started = false;
arguments.function = std::bind(f, args...);
-
+
_joinable = true;
Eina_Bool r = ::eina_lock_new(&arguments.mutex);
if(!r) throw eina::system_error(eina::get_error_code());
eina_lock_free(&arguments.mutex);
}
+ /**
+ * @brief Move constructor. Transfer the thread of execution to the new object.
+ * @param other Another thread object to construct this thread object with.
+ *
+ * This constructor creates a thread object that acquires the thread
+ * of execution represented by @p other. This operation does not
+ * affect the execution of the moved thread, it simply transfers its
+ * handler.
+ *
+ * @note After this call @p other no longer represents a thread of execution.
+ */
thread(thread&& other)
: _joinable(other._joinable), _raw(other._raw)
{
}
+ /**
+ * @brief Transfer the thread of execution.
+ * @param other Another thread object to assign to this thread object.
+ * @note After this call @p other no longer represents a thread of execution.
+ */
thread& operator=(thread&& other)
{
_raw = other._raw;
return *this;
}
+ /**
+ * @brief Destroys the thread object.
+ */
~thread()
{
assert(!joinable());
}
-
+
+ /**
+ * @brief Exchanges the underlying handles of two thread objects.
+ * @param other Another thread object.
+ */
void swap(thread& other) noexcept
{
std::swap(_raw, other._raw);
}
+
+ /**
+ * @brief Check if the thread object identifies an active thread of execution.
+ * @return @c true if the thread object identifies an active thread of execution, @c false otherwise.
+ *
+ * This member function checks if the thread object identifies an
+ * active thread of execution. A default constructed thread is not
+ * joinable, as well as a thread that its members join or detach has
+ * been called.
+ *
+ * A thread that has finished executing code, but has not yet been
+ * joined is still considered an active thread of execution and is
+ * therefore joinable.
+ */
bool joinable() const noexcept
{
return _joinable;
}
+ /**
+ * @brief Wait for the thread to finish its execution.
+ *
+ * This member function blocks the calling thread until the thread
+ * identified by this object finishes its execution.
+ *
+ * @note A joinable thread becomes not joinable after a call to this
+ * function.
+ */
void join()
{
assert(joinable());
_joinable = false;
}
+ /**
+ * @brief Detaches the thread from its handle, making it runs independently.
+ *
+ * This member function separates the thread of execution from the
+ * thread object, allowing execution to continue independently.
+ *
+ * @note After a call to this function, the thread object becomes
+ * non-joinable.
+ */
void detach()
{
assert(joinable());
_joinable = false;
}
+ /**
+ * @brief Returns the identifier of the thread associated with this thread object.
+ * @return <tt>thread::id</tt> identifying the thread associated with this thread object.
+ */
id get_id() const noexcept
{
return id(_raw);
}
+
+ /**
+ * @brief Get a handle for the wrapped @c Eina_Thread.
+ * @return Handle for the native @c Eina_Thread.
+ *
+ * This member function returns the native @c Eina_Thread handle that
+ * is wrapped inside this object.
+ */
native_handle_type native_handle() const
{
return _raw;
}
+ /**
+ * @brief Get the number of hardware concurrent threads.
+ * @return A hint on the number of hardware concurrent threads, or
+ * @c 0 if the value is not well defined or not computable.
+ *
+ * This static member function returns the number of hardware
+ * concurrent threads.
+ *
+ * @note The interpretation of this value is implementation-specific,
+ * and may be just an approximation.
+ */
static unsigned hardware_concurrency() noexcept
{
return ::eina_cpu_count();
}
private:
+ /** @internal */
bool _joinable;
+
+ /** @internal */
Eina_Thread _raw;
};
+/**
+ * @brief Exchanges the underlying handles of two thread objects.
+ * @param lhs First thread object.
+ * @param rhs Second thread object.
+ */
inline void swap(thread& lhs, thread& rhs)
{
lhs.swap(rhs);
namespace this_thread {
+/**
+ * @brief Return identifier of the current thread.
+ * @return <tt>thread::id</tt> identifying the current thread.
+ */
inline thread::id get_id()
{
return thread::id(eina_thread_self());
}
+/**
+ * @brief Provides a hint to the implementation to reschedule the
+ * execution of threads, allowing other threads to run.
+ */
inline void yield() {}
+/**
+ * @brief Block the execution of the current thread until a specified time point.
+ * @param abs_time Point in time when the calling thread shall resume its execution.
+ *
+ * @note This function may block for longer than until after @p rel_time
+ * has been reached due to scheduling or resource contention delays.
+ */
template <typename Clock, typename Duration>
void sleep_until(std::chrono::time_point<Clock, Duration>const& abs_time);
+/**
+ * @brief Block the execution of the current thread for a specified time duration.
+ * @param rel_time Time span after which the calling thread shall resume its execution.
+ *
+ * @note This function may block for longer than @p rel_time due to
+ * scheduling or resource contention delays.
+ */
template <typename Rep, typename Period>
void sleep_for(std::chrono::duration<Rep, Period>const& rel_time);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @internal
+ * Specialization of standard @c hash class to specify that a
+ * <tt>thread_id</tt> object should be handled as a unsigned long
+ * @{
+ */
namespace std {
template <typename T> struct hash;
{};
}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
#endif
#include <string>
#include <vector>
+/**
+ * @addtogroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @internal
+ *
+ * @{
+ */
+
using std::enable_if;
using std::is_integral;
using std::is_pod;
{
};
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif
#include <eina_stringshare.hh>
#include <eina_type_traits.hh>
+/**
+ * @addtogroup Eina_Cxx_Data_Types_Group
+ *
+ * @{
+ */
+
namespace efl { namespace eina {
+/**
+ * @defgroup Eina_Cxx_Value_Group Generic Value Storage
+ * @ingroup Eina_Cxx_Data_Types_Group
+ *
+ * Abstracts generic data storage and access to it in an extensible
+ * and efficient way.
+ *
+ * It is meant for simple data types, providing uniform access, useful
+ * to exchange data preserving their types.
+ *
+ * @{
+ */
+
template <typename T, typename Enable = void>
struct _eina_value_traits;
template <typename T>
struct _eina_value_traits_aux;
+/**
+ * @internal
+ */
template <typename T>
struct _eina_value_traits_base
{
// Indirection for uint64_t. uint64_t can be a typedef for unsigned
// long, so we can't specialize on the same template
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits_aux<uint64_t>
: _eina_value_traits_base<uint64_t>
}
};
+/**
+ * @internal
+ */
template <typename T, typename Enable>
struct _eina_value_traits : _eina_value_traits_aux<T>
{
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<unsigned char>
: _eina_value_traits_base<unsigned char>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<unsigned short>
: _eina_value_traits_base<unsigned short>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<unsigned int>
: _eina_value_traits_base<unsigned int>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<unsigned long>
: _eina_value_traits_base<unsigned long>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<char>
: _eina_value_traits_base<char>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<short>
: _eina_value_traits_base<short>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<int>
: _eina_value_traits_base<int>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<long>
: _eina_value_traits_base<long>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<float>
: _eina_value_traits_base<float>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<double>
: _eina_value_traits_base<double>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<stringshare>
: _eina_value_traits_base<stringshare>
}
};
+/**
+ * @internal
+ */
template <>
struct _eina_value_traits<std::string>
: _eina_value_traits_base<std::string>
}
};
+/**
+ * @internal
+ */
template <typename T>
struct _eina_value_traits<T[], typename eina::enable_if<eina::is_pod<T>::value>::type>
: _eina_value_traits_base<T[]>
template <typename T>
T get(value const& v);
+/**
+ * Store generic value
+ */
class value
{
+ /**
+ * @brief Initialize the <tt>eina::value</tt> with the given argument.
+ * @param v Argument that the <tt>eina::value</tt> will store.
+ */
template <typename T>
void primitive_init(T v)
{
_eina_value_traits<T>::set(_raw, v);
}
public:
+
+ /**
+ * @brief Default constructor. Create an empty generic value storage.
+ */
value()
: _raw(_eina_value_traits<char>::create())
{
}
+
+ /**
+ * @brief Create an generic value storage holding the given argument.
+ * @param v Value to be stored.
+ */
template <typename T>
value(T v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c char value.
+ * @param v @c char value to be stored.
+ */
value(char v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c short value.
+ * @param v @c short value to be stored.
+ */
value(short v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c int value.
+ * @param v @c int value to be stored.
+ */
value(int v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c long value.
+ * @param v @c long value to be stored.
+ */
value(long v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a <tt>unsigned char</tt> value.
+ * @param v <tt>unsigned char</tt> value to be stored.
+ */
value(unsigned char v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a <tt>unsigned short</tt> value.
+ * @param v <tt>unsigned short</tt> value to be stored.
+ */
value(unsigned short v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a <tt>unsigned int</tt> value.
+ * @param v <tt>unsigned int</tt> value to be stored.
+ */
value(unsigned int v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a <tt>unsigned long</tt> value.
+ * @param v <tt>unsigned long</tt> value to be stored.
+ */
value(unsigned long v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c float value.
+ * @param v @c float value to be stored.
+ */
value(float v)
{
primitive_init(v);
}
+
+ /**
+ * @brief Create an generic value storage holding a @c double value.
+ * @param v @c double value to be stored.
+ */
value(double v)
{
primitive_init(v);
}
+ /**
+ * @brief Deallocate stored value.
+ */
~value()
{
eina_value_free(_raw);
}
+ /**
+ * @brief Copy Constructor. Create an generic value storage holding the same value of @p other.
+ * @param other Another <tt>eina::value</tt> object.
+ */
value(value const& other)
: _raw(_eina_value_traits<char>::create())
{
if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
throw eina::system_error(eina::get_error_code());
}
+
+ /**
+ * @brief Assignment operator. Replace the current stored value by the value in @p other.
+ * @param other Another <tt>eina::value</tt> object.
+ */
value& operator=(value const& other)
{
eina_value_flush(_raw);
return *this;
}
+ /**
+ * @brief Swap stored values with the given <tt>eina::value</tt> object.
+ * @param other Another <tt>eina::value</tt> object.
+ */
void swap(value& other)
{
std::swap(_raw, other._raw);
}
+ /**
+ * @brief Get a handle for the wrapped @c Eina_Value.
+ * @return Handle for the native @c Eina_Value.
+ *
+ * This member function returns the native @c Eina_Value handle that
+ * is wrapped inside this object.
+ *
+ * @warning It is important to take care when using it, since the
+ * handle will be automatically released upon object destruction.
+ */
typedef Eina_Value* native_handle_type;
native_handle_type native_handle() const
{
return _raw;
}
+
+ /**
+ * Type for a constant pointer to an @c Eina_Value_Type.
+ * Describes the type of the data being stored.
+ */
typedef Eina_Value_Type const* type_info_t;
+
+ /**
+ * @brief Get an identifier for the type of the value currently stored.
+ * @return @c Eina_Value_Type instance or @c NULL if type is invalid.
+ */
type_info_t type_info() const
{
return ::eina_value_type_get(_raw);
private:
::Eina_Value* _raw;
+ /**
+ * @brief Get the data stored in the given <tt>eina::value</tt>.
+ * @param v <tt>eina::value</tt> object.
+ * @param T Type of the value stored.
+ * @return Copy of the value stored in @p v.
+ * @throw <tt>eina::system_error</tt> with error the code
+ * @c EINA_ERROR_VALUE_FAILED if @p T doesn't match the type of
+ * the value currently stored. Or <tt>eina::system_error</tt>
+ * with an internal Eina error code if the operation fails for
+ * another reason.
+ *
+ * This function returns the value stored in @p v. The type of the
+ * value must be specified via the template parameter @p T, and must
+ * match the current stored value type.
+ */
template <typename T>
friend T get(value const& v)
{
}
};
+/**
+ * @brief Swap the stored values between the given <tt>eina::value</tt> objects.
+ * @param lhs First <tt>eina::value</tt> object.
+ * @param rhs Second <tt>eina::value</tt> object.
+ */
inline void swap(value& lhs, value& rhs)
{
lhs.swap(rhs);
}
+/**
+ * @brief Compare if the stored values are equal.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return @c true if the stored values are of the same type and equals
+ * in content, @c false otherwise.
+ */
inline bool operator==(value const& lhs, value const& rhs)
{
return lhs.type_info() == rhs.type_info()
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) == 0;
}
+/**
+ * @brief Less than comparison between two <tt>eina::value</tt> objects.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return For objects holding values of the same type, returns @c true
+ * if @p lhs value is less than @p rhs value. For objects
+ * holding values of different types, returns @c true if the
+ * type identifier of @p lhs comes before the type indentifier
+ * of @p rhs. Returns @c false in all other cases.
+ */
inline bool operator<(value const& lhs, value const& rhs)
{
return std::less<Eina_Value_Type const*>()(lhs.type_info(), rhs.type_info())
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) < 0);
}
+/**
+ * @brief More than comparison between two <tt>eina::value</tt> objects.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return For objects holding values of the same type, returns @c true
+ * if @p lhs value is more than @p rhs value. For objects
+ * holding values of different types, returns @c true if the
+ * type identifier of @p lhs comes after the type indentifier
+ * of @p rhs. Returns @c false in all other cases.
+ */
inline bool operator>(value const& lhs, value const& rhs)
{
return std::less<Eina_Value_Type const*>()(rhs.type_info(), lhs.type_info())
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) > 0);
}
+/**
+ * @brief Less than or equal comparison between two <tt>eina::value</tt> objects.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return For objects holding values of the same type, returns @c true
+ * if @p lhs value is less than or equal to @p rhs value. For
+ * objects holding values of different types, returns @c true if
+ * the type identifier of @p lhs comes before the type
+ * indentifier of @p rhs. Returns @c false in all other cases.
+ */
inline bool operator<=(value const& lhs, value const& rhs)
{
return !(lhs > rhs);
}
+/**
+ * @brief More than or equal comparison between two <tt>eina::value</tt> objects.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return For objects holding values of the same type, returns @c true
+ * if @p lhs value is more than or equal to @p rhs value. For
+ * objects holding values of different types, returns @c true if
+ * the type identifier of @p lhs comes after the type
+ * indentifier of @p rhs. Returns @c false in all other cases.
+ */
inline bool operator>=(value const& lhs, value const& rhs)
{
return !(lhs < rhs);
}
+/**
+ * @brief Compare if the stored values are different.
+ * @param lhs <tt>eina::value</tt> object at the left side of the expression.
+ * @param rhs <tt>eina::value</tt> object at the right side of the expression.
+ * @return @c true if the value types are different or if the value of
+ * @p lhs is different from the value of @rhs, @c false
+ * otherwise.
+ */
inline bool operator!=(value const& lhs, value const& rhs)
{
return !(lhs == rhs);
}
+/**
+ * @}
+ */
+
} }
+/**
+ * @}
+ */
+
#endif