forked from enlightenment/efl
eina_cxx: add documentation to the Eina C++ header files.
Summary: Added documentation to almost all classes that are intended for direct use by the library users. Marked classes/functions used by the library itself as @internal. Modified the Doxyfile.in to enable the generation of documentation to the bindings. Reviewers: felipealmeida, cedric, woohyun, smohanty, raster CC: savio, cedric Differential Revision: https://phab.enlightenment.org/D947 Signed-off-by: Cedric BAIL <c.bail@partner.samsung.com>
This commit is contained in:
parent
5e7a9b1225
commit
0902b6a6f8
|
@ -594,6 +594,7 @@ WARN_LOGFILE =
|
|||
# with spaces.
|
||||
|
||||
INPUT = @top_srcdir@/src/lib \
|
||||
@top_srcdir@/src/bindings \
|
||||
@srcdir@/main.dox \
|
||||
@srcdir@/pkgconfig.dox \
|
||||
@srcdir@/eina_examples.dox \
|
||||
|
@ -626,7 +627,8 @@ INPUT_ENCODING = UTF-8
|
|||
|
||||
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.
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef EINA_HH_
|
||||
#define EINA_HH_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Eina C++
|
||||
*/
|
||||
|
||||
#include <eina_iterator.hh>
|
||||
#include <eina_ptrarray.hh>
|
||||
#include <eina_ptrlist.hh>
|
||||
|
@ -16,8 +21,37 @@
|
|||
#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()
|
||||
|
@ -30,6 +64,12 @@ struct 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()
|
||||
|
@ -42,6 +82,10 @@ struct eina_threads_init
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,25 +9,82 @@
|
|||
#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);
|
||||
|
@ -36,11 +93,25 @@ struct accessor
|
|||
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);
|
||||
|
@ -53,98 +124,242 @@ struct accessor
|
|||
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;
|
||||
|
||||
private:
|
||||
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)
|
||||
|
@ -152,6 +367,12 @@ private:
|
|||
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
|
||||
|
@ -161,6 +382,12 @@ private:
|
|||
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
|
||||
|
@ -169,12 +396,26 @@ private:
|
|||
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)
|
||||
{
|
||||
|
@ -182,30 +423,63 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
|
@ -6,8 +6,31 @@
|
|||
#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>
|
||||
|
@ -27,6 +50,11 @@ struct heap_copy_allocator
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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>
|
||||
|
@ -41,6 +69,14 @@ struct heap_clone_allocator
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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>
|
||||
|
@ -54,6 +90,11 @@ struct view_clone_allocator
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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>
|
||||
|
@ -65,8 +106,15 @@ struct heap_no_copy_allocator
|
|||
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>
|
||||
|
@ -86,6 +134,14 @@ struct malloc_clone_allocator
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,48 +5,129 @@
|
|||
|
||||
#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);
|
||||
|
@ -54,12 +135,29 @@ struct error_category : system_error_category
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
@ -72,6 +170,14 @@ inline eina::error_code get_error_code()
|
|||
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())
|
||||
|
@ -80,6 +186,13 @@ inline void set_error_code(eina::error_code const& e)
|
|||
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();
|
||||
|
@ -92,12 +205,35 @@ inline eina::error_condition get_error_condition()
|
|||
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();
|
||||
|
@ -107,13 +243,28 @@ inline void throw_on_error()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} }
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,8 +10,24 @@
|
|||
#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
|
||||
{
|
||||
|
@ -19,18 +35,27 @@ 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)
|
||||
{
|
||||
|
@ -40,38 +65,85 @@ 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)
|
||||
|
@ -80,32 +152,65 @@ struct _inlist_iterator
|
|||
_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)
|
||||
|
@ -114,12 +219,21 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -242,49 +356,93 @@ struct _inlist_access_traits {
|
|||
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;
|
||||
|
@ -301,11 +459,18 @@ struct _inlist_common_base
|
|||
}
|
||||
_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
|
||||
{
|
||||
|
@ -317,40 +482,77 @@ struct _inlist_common_base
|
|||
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 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;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
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()
|
||||
|
@ -363,29 +565,74 @@ public:
|
|||
++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) );
|
||||
|
@ -401,6 +648,15 @@ public:
|
|||
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) );
|
||||
|
@ -416,14 +672,36 @@ public:
|
|||
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) );
|
||||
|
@ -442,6 +720,21 @@ public:
|
|||
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;
|
||||
|
@ -452,6 +745,18 @@ public:
|
|||
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)
|
||||
|
@ -471,6 +776,15 @@ public:
|
|||
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())
|
||||
|
@ -483,6 +797,20 @@ public:
|
|||
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)
|
||||
|
@ -493,6 +821,18 @@ public:
|
|||
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)
|
||||
|
@ -501,99 +841,296 @@ public:
|
|||
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)
|
||||
{
|
||||
|
@ -601,18 +1138,33 @@ bool operator==(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& r
|
|||
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
|
||||
|
|
|
@ -1,18 +1,42 @@
|
|||
#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)...> {};
|
||||
|
@ -21,6 +45,10 @@ template<class S1, class S2>
|
|||
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>
|
||||
|
@ -30,12 +58,26 @@ struct gen_seq : Concat<make_integer_sequence<T, N/2>
|
|||
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
|
||||
|
|
|
@ -6,33 +6,86 @@
|
|||
#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;
|
||||
|
@ -41,38 +94,76 @@ public:
|
|||
}
|
||||
|
||||
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;
|
||||
|
@ -82,20 +173,45 @@ public:
|
|||
_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
|
||||
|
|
|
@ -3,8 +3,17 @@
|
|||
|
||||
#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)
|
||||
|
@ -13,6 +22,9 @@ inline Eina_List* _eina_list_prepend_relative_list(Eina_List* list, const void*
|
|||
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)
|
||||
|
@ -25,4 +37,8 @@ inline Eina_Inlist *_eina_inlist_prepend_relative(Eina_Inlist *in_list,
|
|||
|
||||
} }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,39 +3,102 @@
|
|||
|
||||
#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>
|
||||
|
@ -43,35 +106,72 @@ struct _domain_base
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
|
@ -79,6 +179,17 @@ inline void _log(std::stringstream const& stream, int domain, ::Eina_Log_Level l
|
|||
, "%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 ; \
|
||||
|
@ -86,39 +197,157 @@ inline void _log(std::stringstream const& stream, int domain, ::Eina_Log_Level l
|
|||
, __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
|
||||
|
|
|
@ -5,8 +5,17 @@
|
|||
#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)
|
||||
{
|
||||
|
@ -18,34 +27,105 @@ 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)
|
||||
{
|
||||
|
@ -53,6 +133,16 @@ struct optional
|
|||
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();
|
||||
|
@ -62,6 +152,17 @@ struct optional
|
|||
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);
|
||||
|
@ -69,37 +170,80 @@ struct optional
|
|||
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())
|
||||
|
@ -118,11 +262,19 @@ struct optional
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
|
@ -130,6 +282,10 @@ private:
|
|||
new (&buffer) T(std::move(object));
|
||||
engaged = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
void _destroy()
|
||||
{
|
||||
if(is_engaged())
|
||||
|
@ -141,16 +297,36 @@ private:
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -161,11 +337,28 @@ 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)
|
||||
{
|
||||
|
@ -178,22 +371,60 @@ 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_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,159 +1,377 @@
|
|||
#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_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;
|
||||
typedef _const_range_template<T, Traits> _self_type;
|
||||
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;
|
||||
, _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;
|
||||
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;
|
||||
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)
|
||||
{}
|
||||
|
@ -175,6 +393,14 @@ protected:
|
|||
using _base_type::_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,24 +3,75 @@
|
|||
|
||||
#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
|
||||
|
|
|
@ -7,11 +7,58 @@
|
|||
#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;
|
||||
|
@ -24,17 +71,64 @@ struct stringshare
|
|||
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
|
||||
|
@ -50,6 +144,14 @@ struct stringshare
|
|||
}
|
||||
_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
|
||||
|
@ -58,81 +160,225 @@ struct stringshare
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @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())
|
||||
|
@ -140,66 +386,143 @@ struct stringshare
|
|||
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
|
||||
|
|
|
@ -13,23 +13,72 @@
|
|||
#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);
|
||||
|
@ -44,6 +93,20 @@ struct 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);
|
||||
|
@ -60,6 +123,21 @@ struct 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);
|
||||
|
@ -74,37 +152,114 @@ struct 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);
|
||||
|
@ -112,6 +267,15 @@ struct condition_variable
|
|||
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);
|
||||
|
@ -119,6 +283,16 @@ struct condition_variable
|
|||
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)
|
||||
{
|
||||
|
@ -127,47 +301,121 @@ struct condition_variable
|
|||
::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)
|
||||
|
@ -176,21 +424,53 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
@ -199,6 +479,9 @@ struct arguments
|
|||
std::function<void()> function;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
inline void* create_thread(void* data, Eina_Thread)
|
||||
{
|
||||
arguments* args = static_cast<arguments*>(data);
|
||||
|
@ -217,23 +500,47 @@ inline void* create_thread(void* data, Eina_Thread)
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
|
@ -264,11 +571,27 @@ struct thread
|
|||
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;
|
||||
|
@ -276,20 +599,50 @@ struct thread
|
|||
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());
|
||||
|
@ -297,30 +650,70 @@ struct thread
|
|||
_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);
|
||||
|
@ -328,22 +721,54 @@ inline void swap(thread& lhs, thread& 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;
|
||||
|
@ -352,5 +777,12 @@ struct hash< ::efl::eina::thread_id> : hash<unsigned long>
|
|||
{};
|
||||
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,8 +6,20 @@
|
|||
#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;
|
||||
|
@ -46,6 +58,14 @@ struct if_ : if_c<U::value, T, F>
|
|||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
} }
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,8 +6,27 @@
|
|||
#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;
|
||||
|
||||
|
@ -17,6 +36,9 @@ struct _eina_value_traits_base;
|
|||
template <typename T>
|
||||
struct _eina_value_traits_aux;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <typename T>
|
||||
struct _eina_value_traits_base
|
||||
{
|
||||
|
@ -51,6 +73,9 @@ 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>
|
||||
|
@ -61,11 +86,17 @@ struct _eina_value_traits_aux<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>
|
||||
|
@ -76,6 +107,9 @@ struct _eina_value_traits<unsigned char>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<unsigned short>
|
||||
: _eina_value_traits_base<unsigned short>
|
||||
|
@ -86,6 +120,9 @@ struct _eina_value_traits<unsigned short>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<unsigned int>
|
||||
: _eina_value_traits_base<unsigned int>
|
||||
|
@ -96,6 +133,9 @@ struct _eina_value_traits<unsigned int>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<unsigned long>
|
||||
: _eina_value_traits_base<unsigned long>
|
||||
|
@ -106,6 +146,9 @@ struct _eina_value_traits<unsigned long>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<char>
|
||||
: _eina_value_traits_base<char>
|
||||
|
@ -116,6 +159,9 @@ struct _eina_value_traits<char>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<short>
|
||||
: _eina_value_traits_base<short>
|
||||
|
@ -126,6 +172,9 @@ struct _eina_value_traits<short>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<int>
|
||||
: _eina_value_traits_base<int>
|
||||
|
@ -136,6 +185,9 @@ struct _eina_value_traits<int>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<long>
|
||||
: _eina_value_traits_base<long>
|
||||
|
@ -146,6 +198,9 @@ struct _eina_value_traits<long>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<float>
|
||||
: _eina_value_traits_base<float>
|
||||
|
@ -156,6 +211,9 @@ struct _eina_value_traits<float>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<double>
|
||||
: _eina_value_traits_base<double>
|
||||
|
@ -166,6 +224,9 @@ struct _eina_value_traits<double>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<stringshare>
|
||||
: _eina_value_traits_base<stringshare>
|
||||
|
@ -186,6 +247,9 @@ struct _eina_value_traits<stringshare>
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
template <>
|
||||
struct _eina_value_traits<std::string>
|
||||
: _eina_value_traits_base<std::string>
|
||||
|
@ -209,6 +273,9 @@ struct _eina_value_traits<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[]>
|
||||
|
@ -237,8 +304,15 @@ class value;
|
|||
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)
|
||||
{
|
||||
|
@ -246,67 +320,138 @@ class value
|
|||
_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);
|
||||
|
@ -315,17 +460,41 @@ public:
|
|||
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);
|
||||
|
@ -333,6 +502,21 @@ public:
|
|||
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)
|
||||
{
|
||||
|
@ -340,17 +524,39 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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())
|
||||
|
@ -358,6 +564,16 @@ inline bool operator<(value const& lhs, value const& rhs)
|
|||
&& 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())
|
||||
|
@ -365,21 +581,57 @@ inline bool operator>(value const& lhs, value const& rhs)
|
|||
&& 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
|
||||
|
|
Loading…
Reference in New Issue