From 0902b6a6f8ce10aefc9c19d455fd5c176e2bd53a Mon Sep 17 00:00:00 2001 From: "vitor.sousa" Date: Wed, 4 Jun 2014 22:34:42 +0200 Subject: [PATCH] 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 --- doc/Doxyfile.in | 4 +- src/bindings/eina_cxx/Eina.hh | 44 + src/bindings/eina_cxx/eina_accessor.hh | 300 ++++- .../eina_cxx/eina_clone_allocators.hh | 58 +- src/bindings/eina_cxx/eina_error.hh | 155 ++- src/bindings/eina_cxx/eina_inarray.hh | 1122 ++++++++++++++++- src/bindings/eina_cxx/eina_inlist.hh | 608 ++++++++- .../eina_cxx/eina_integer_sequence.hh | 46 +- src/bindings/eina_cxx/eina_iterator.hh | 144 ++- src/bindings/eina_cxx/eina_lists_auxiliary.hh | 16 + src/bindings/eina_cxx/eina_log.hh | 229 ++++ src/bindings/eina_cxx/eina_optional.hh | 233 +++- src/bindings/eina_cxx/eina_ptrarray.hh | 670 +++++++++- src/bindings/eina_cxx/eina_ptrlist.hh | 704 ++++++++++- src/bindings/eina_cxx/eina_range_types.hh | 290 ++++- src/bindings/eina_cxx/eina_ref.hh | 53 +- src/bindings/eina_cxx/eina_stringshare.hh | 331 ++++- src/bindings/eina_cxx/eina_thread.hh | 450 ++++++- src/bindings/eina_cxx/eina_type_traits.hh | 20 + src/bindings/eina_cxx/eina_value.hh | 252 ++++ 20 files changed, 5539 insertions(+), 190 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 0086929fc6..a1b2c0cbe3 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -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. diff --git a/src/bindings/eina_cxx/Eina.hh b/src/bindings/eina_cxx/Eina.hh index 9ba0ca3ebc..ed25c3c29f 100644 --- a/src/bindings/eina_cxx/Eina.hh +++ b/src/bindings/eina_cxx/Eina.hh @@ -1,6 +1,11 @@ #ifndef EINA_HH_ #define EINA_HH_ +/** + * @file + * @brief Eina C++ + */ + #include #include #include @@ -16,8 +21,37 @@ #include #include +/** + * @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 diff --git a/src/bindings/eina_cxx/eina_accessor.hh b/src/bindings/eina_cxx/eina_accessor.hh index 5798c9b5e5..22b4841774 100644 --- a/src/bindings/eina_cxx/eina_accessor.hh +++ b/src/bindings/eina_cxx/eina_accessor.hh @@ -9,25 +9,82 @@ #include #include +/** + * @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 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 const& other) : _impl(eina_accessor_clone(other._impl)) {} + + /** + * @brief Assignment Operator. Replace the current content. + * @param other Other accessor object. + * @throw eina::system_error 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& operator=(accessor 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 eina::system_error 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 + * eina::system_error is thrown. + */ mapped_type& operator[](size_type i) const { assert(_impl != 0); @@ -53,98 +124,242 @@ struct accessor return *static_cast(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& 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::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 void swap(accessor& lhs, accessor& rhs) { lhs.swap(rhs); } +/** + * @} + */ + +/** + * @defgroup Eina_Cxx_Accessor_Iterator_Group Accessor Iterator + * @ingroup Eina_Cxx_Content_Access_Group + * + * @{ + */ + +/** + * Random access iterator for eina::accessor. + */ template 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 eina::accessor. + * @param a eina::accessor object. + * @param pos Initial position of the iterator (Default = @c 0). + * + * This constructor creates an @c accessor_iterator for the given + * eina::accessor 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 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& 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& 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& 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& 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& operator++(int) { accessor_iterator 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& operator--(int) { accessor_iterator 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& other) { std::swap(_index, other._index); std::swap(_accessor, other._accessor); } -private: - accessor _accessor; - unsigned int _index; +private: + accessor _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 friend bool operator==(accessor_iterator const& lhs, accessor_iterator const& rhs) { return lhs._index == rhs._index; } + /** + * @brief Get the distance between two accessor_iterators. + * @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 friend typename accessor_iterator::difference_type operator-(accessor_iterator const& lhs, accessor_iterator 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 friend accessor_iterator operator+(accessor_iterator 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 friend accessor_iterator operator+(typename accessor_iterator::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 friend bool operator<(accessor_iterator const& lhs, accessor_iterator 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 friend bool operator<=(accessor_iterator const& lhs, accessor_iterator 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 bool operator>=(accessor_iterator const& lhs, accessor_iterator 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 bool operator>(accessor_iterator const& lhs, accessor_iterator 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 bool operator!=(accessor_iterator const& lhs, accessor_iterator const& rhs) { return !(lhs == rhs); } +/** + * @brief Swap content between two accessor_iterators. + * @param lhs First @c accessor_iterator. + * @param rhs Second @c accessor_iterator. + */ template void swap(accessor_iterator& lhs, accessor_iterator& rhs) { lhs.swap(rhs); } +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_clone_allocators.hh b/src/bindings/eina_cxx/eina_clone_allocators.hh index 9174eee609..2e8ae4516b 100644 --- a/src/bindings/eina_cxx/eina_clone_allocators.hh +++ b/src/bindings/eina_cxx/eina_clone_allocators.hh @@ -6,8 +6,31 @@ #include #include +/** + * @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 @@ -27,6 +50,11 @@ struct heap_copy_allocator } }; +/** + * This allocator allows users to create custom allocation schemes by + * overloading the new_clone(T const& v) and + * delete_clone(T* p) functions. + */ struct heap_clone_allocator { template @@ -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 @@ -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 @@ -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 + * standard-layout. + */ struct malloc_clone_allocator { template @@ -86,6 +134,14 @@ struct malloc_clone_allocator } }; +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_error.hh b/src/bindings/eina_cxx/eina_error.hh index 9962768799..d2718ca326 100644 --- a/src/bindings/eina_cxx/eina_error.hh +++ b/src/bindings/eina_cxx/eina_error.hh @@ -5,48 +5,129 @@ #include +/** + * @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. + * + * @{ + */ + +/** std::errc for Eina errors. */ using std::errc; + +/** std::system_error for Eina errors. */ using std::system_error; + +/** std::error_code for Eina errors. */ using std::error_code; + +/** std::error_condition for Eina errors. */ using std::error_condition; + +/** std::error_category 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 std::generic_category instance as a eina::system_error_category. + * @return a std::generic_category instance as a eina::system_error_category. + */ inline system_error_category const& get_generic_category() { return ::std::generic_category(); } + +/** + * @brief Gets a std::system_category instance as a eina::system_error_category. + * @return std::system_category instance as a eina::system_error_category. + */ 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 eina::error_condition 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 eina::error_code 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 eina::error_category object. + * @return Reference to a static instance of an eina::error_category. + */ 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 eina::error_code for the last Eina error. + * + * This function gets the error code for the last Eina error and + * consumes it. The category of the returned eina::error_code + * 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 eina::error_code 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 eina::error_condition for the last Eina error. + * + * This function works exactly like @ref get_error_code but returns an + * eina::error_condition 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( ::eina_error_get() ); } +/** + * @brief Throw an exception if there is a error set in Eina library. + * @throw eina::system_error 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 eina::error_code 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 diff --git a/src/bindings/eina_cxx/eina_inarray.hh b/src/bindings/eina_cxx/eina_inarray.hh index 4b10735d76..ae593e4896 100644 --- a/src/bindings/eina_cxx/eina_inarray.hh +++ b/src/bindings/eina_cxx/eina_inarray.hh @@ -9,232 +9,538 @@ #include #include +/** + * @addtogroup Eina_Cxx_Containers_Group + * + * @{ + */ + namespace efl { namespace eina { +/** + * @defgroup Eina_Cxx_Inline_Array_Group Inline Array + * @ingroup Eina_Cxx_Containers_Group + * + * Inline array is a container that stores the data itself not pointers to data, + * this means there is no memory fragmentation, also for small data types(such + * as char, short, int, etc.) it's more memory efficient. + * + * @{ + */ + +/** + * @internal + * Access traits for eina::inarray. + */ struct _inarray_access_traits { template struct const_iterator { - typedef T const* type; + typedef T const* type; /**< Type for constant iterator. */ }; template struct iterator { - typedef T* type; + typedef T* type; /**< Type for iterator. */ }; template struct const_native_handle { - typedef Eina_Inarray const* type; + typedef Eina_Inarray const* type; /**< Type for constant native @c Eina_Inarray handle. */ }; template struct native_handle { - typedef Eina_Inarray* type; + typedef Eina_Inarray* type; /**< Type for native @c Eina_Inarray handle. */ }; + /** + * @brief Get a non-constant native @c Eina_Inarray handle from a constant one. + */ template static Eina_Inarray* native_handle_from_const(Eina_Inarray const* array) { return const_cast(array); } + +/** + * @brief Get a reference to the last element of the given @c Eina_Inarray. + */ template static T& back(Eina_Inarray* raw) { assert(!_inarray_access_traits::empty(raw)); return *static_cast( ::eina_inarray_nth(raw, _inarray_access_traits::size(raw)-1u)); } +/** + * @brief Get a constant reference to the last element of the given @c Eina_Inarray. + * + * Version of @ref back(Eina_Inarray* raw) for const-qualified pointer + * to @c Eina_Inarray. Get a constant reference to the last element + * instead. + */ template static T const& back(Eina_Inarray const* raw) { return _inarray_access_traits::back(const_cast(raw)); } + +/** + * @brief Get a reference to the first element of the given @c Eina_Inarray. + */ template static T& front(Eina_Inarray* raw) { assert(!empty(raw)); return *static_cast( ::eina_inarray_nth(raw, 0u)); } + +/** + * @brief Get a constant reference to the first element of the given @c Eina_Inarray. + * + * Version of @ref front(Eina_Inarray* raw) for const-qualified + * pointer to @c Eina_Inarray. Get a constant reference to the first + * element instead. + */ template static T const& front(Eina_Inarray const* raw) { return _inarray_access_traits::front(const_cast(raw)); } + +/** + * @brief Get an iterator to the begin of the memory block of the given @c Eina_Inarray. + */ template static T* begin(Eina_Inarray* raw) { return !raw->members ? 0 : static_cast( ::eina_inarray_nth(raw, 0u)); } + +/** + * @brief Get an iterator to the end of the memory block of the given @c Eina_Inarray. + */ template static T* end(Eina_Inarray* raw) { return !raw->members ? 0 : static_cast( ::eina_inarray_nth(raw, _inarray_access_traits::size(raw) -1)) + 1; } + +/** + * @brief Get a constant iterator to the begin of the memory block of the given @c Eina_Inarray. + * + * Version of @ref begin(Eina_Inarray* raw) for const-qualified + * @c Eina_Inarray handles. Returns a constant iterator instead. + */ template static T const* begin(Eina_Inarray const* raw) { return _inarray_access_traits::begin(const_cast(raw)); } + + +/** + * @brief Get a constant iterator to the end of the memory block of the given @c Eina_Inarray. + * + * Version of @ref end(Eina_Inarray* raw) const-qualified + * @c Eina_Inarray. Returns a constant iterator instead. + */ template static T const* end(Eina_Inarray const* raw) { return _inarray_access_traits::end(const_cast(raw)); } + +/** + * @brief Get a constant reverse iterator pointing to the reverse begin of the given Eina_Inarray. + * + * Version of @ref rbegin(Eina_Inarray* raw) for const-qualified + * Eina_Inarray handles. Returns a constant reverse iterator instead. + */ template static std::reverse_iterator rbegin(Eina_Inarray const* raw) { return std::reverse_iterator(_inarray_access_traits::end(raw)); } + +/** + * @brief Get a constant reverse iterator pointing to the reverse end of the given Eina_Inarray. + * + * Version of @ref rend(Eina_Inarray* raw) to const-qualified + * Eina_Inarray handles. Returns a constant reverse iterator instead. + */ template static std::reverse_iterator rend(Eina_Inarray const* raw) { return std::reverse_iterator(_inarray_access_traits::begin(raw)); } + +/** + * @brief Get a reverse iterator pointing to the reverse begin of the given @c Eina_Inarray. + */ template static std::reverse_iterator rbegin(Eina_Inarray* raw) { return std::reverse_iterator(_inarray_access_traits::end(raw)); } + +/** + * @brief Get a reverse iterator pointing to the reverse end of the given @c Eina_Inarray. + */ template static std::reverse_iterator rend(Eina_Inarray* raw) { return std::reverse_iterator(_inarray_access_traits::begin(raw)); } + +/** + * @brief Get a constant iterator to the begin of the memory block of the given @c Eina_Inarray. + * + * Works like @ref begin(Eina_Inarray const* raw) but is granted to + * return a constant iterator even for handles that are not + * const-qualified. + */ template static T const* cbegin(Eina_Inarray const* raw) { return _inarray_access_traits::begin(raw); } + +/** + * @brief Get a constant iterator to the end of the memory block of the given @c Eina_Inarray. + * + * Works like @ref end(Eina_Inarray const* raw) but is granted to + * return a constant iterator even for handles that are not + * const-qualified. + */ template static T const* cend(Eina_Inarray const* raw) { return _inarray_access_traits::end(raw); } + +/** + * @brief Get a constant reverse iterator to the end of the memory block of the given @c Eina_Inarray. + * + * Works like @ref rbegin(Eina_Inarray const* raw) but is granted to + * return a constant reverse iterator even for handles that are not + * const-qualified. + */ template static std::reverse_iterator crbegin(Eina_Inarray const* raw) { return _inarray_access_traits::rbegin(raw); } + +/** + * @brief Get a constant reverse iterator to the begin of the memory block of the given @c Eina_Inarray. + * + * Works like @ref rend(Eina_Inarray const* raw) but is granted to + * return a constant reverse iterator even for handles that are not + * const-qualified. + */ template static std::reverse_iterator crend(Eina_Inarray const* raw) { return _inarray_access_traits::rend(raw); } + +/** + * @brief Check if the given Eina array is empty. + * @return @c true if the given array is empty, @c false otherwise. + * + * This functions returns @c true if the given @c Eina_Inarray contains + * no elements, otherwise it returns @c false. + */ template static inline bool empty(Eina_Inarray const* raw) { return _inarray_access_traits::size(raw) == 0; } + +/** + * @brief Get the size of the given @c Eina_Inarray. + * @return Number of elements in the given array. + * + * This function returns the current number of elements inside of @p raw. + */ template static inline std::size_t size(Eina_Inarray const* raw) { return ::eina_inarray_count(raw); } + +/** + * @brief Get a constant reference to the element at the given position. + * @param raw Constant pointer to an @c Eina_Inarray. + * @param i Position of the element. + * @return Constant reference to the element. + * + * Version of @ref index() for const-qualified @c Eina_Inarray. Returns + * a constant reference instead. + */ template static T const& index(Eina_Inarray const* raw, std::size_t i) { return *(_inarray_access_traits::begin(raw) + i); } + +/** + * @brief Get a reference to the element at the given position. + * @param raw Pointer to a @c Eina_Inarray. + * @param i Position of the element. + * @return Reference to the element. + * + * This member function returns a reference to the element at position + * @p i inside @p raw. + */ template static T& index(Eina_Inarray* raw, std::size_t i) { return *(_inarray_access_traits::begin(raw) + i); } + }; template class inarray; +/** + * @ingroup Eina_Cxx_Range_Group + * + * Range class for @ref inarray. + */ template struct range_inarray : _range_template { - typedef _range_template _base_type; - typedef typename std::remove_const::type value_type; + typedef _range_template _base_type; /**< Type for the base class. */ + typedef typename std::remove_const::type value_type; /**< The type of each element. */ + /** + * @brief Creates a range from a native Eina inline array handle. + */ range_inarray(Eina_Inarray* array) : _base_type(array) {} + + /** + * @brief Creates a range from a @c inarray object. + */ range_inarray(inarray& array) : _base_type(array.native_handle()) {} + /** + * @brief Get the element at the given position in the array. + * @param index Position of the element. + * @return Reference to the element at the given position. + */ value_type& operator[](std::size_t index) const { return _inarray_access_traits::index(this->native_handle(), index); } }; +/** + * Common inarray interface for every value type. + */ struct _inarray_common_base { - typedef std::size_t size_type; - typedef Eina_Inarray* native_handle_type; - typedef Eina_Inarray const* const_native_handle_type; + typedef std::size_t size_type; /**< Type for size information used in the array. */ + typedef Eina_Inarray* native_handle_type; /** Type for the native @c Eina_Inarray handle. */ + typedef Eina_Inarray const* const_native_handle_type; /** Type for constant native @c Eina_Inarray handle. */ + /** + * @brief Creates a new array object from a handle to a native @c Eina_Inarray. + * @param array Handler to a native @c Eina_Inarray + * + * This constructor wraps a pre-allocated @c Eina_Inarray providing an + * OO interface to it. + * + * @warning It is important to note that the created array object + * gains ownership of the handle, deallocating it at destruction time. + */ explicit _inarray_common_base(Eina_Inarray* array) : _array(array) {} + + /** + * @brief Allocates a array with the given size for each element. + * @param member_size Size of each element in the array. + * + * This constructor creates an inline array object with the given + * size (in bytes) for each element. All allocated memory will be + * released at destruction. + */ explicit _inarray_common_base(size_type member_size) : _array( ::eina_inarray_new(member_size, 0) ) { } + + /** + * @brief Release the inline array memory. + * + * This destructor release the internal native @c Eina_Inarray handle, + * freeing allocated memory. + */ ~_inarray_common_base() { ::eina_inarray_free(_array); } - + + /** + * @brief Get the current size of the array. + * @return Number of elements in the array. + * + * This member function returns the current number of elements inside + * the inline array. + */ size_type size() const { return _inarray_access_traits::size(_array); } + + /** + * @brief Check if the array is empty. + * @return @c true if the array is empty, @c false otherwise. + * + * This member function returns @c true if the array does not contain + * any elements, otherwise it returns @c false. + */ bool empty() const { return _inarray_access_traits::empty(_array); } + + /** + * @brief Get the handle for the wrapped Eina_Inarray. + * @return Internal handle for the native Eina inline array. + * + * This member function returns the native @c Eina_Inarray handle that + * is wrapped inside this object. + * + * @warning It is important to take care when using it, since the + * handle will be automatically release upon object destruction. + */ native_handle_type native_handle() { return _array; } + + /** + * @brief Get a constant handle for the wrapped Eina_Inarray. + * @return Constant handle for the native Eina inline array. + * + * Version of @ref native_handle() for const-qualified objects. + * Return a constant handle instead. + */ const_native_handle_type native_handle() const { return _array; } + /** + * @internal + * Member variable that holds the native @c Eina_Inarray handle. + */ Eina_Inarray* _array; private: + /** Disabled copy constructor. */ _inarray_common_base(_inarray_common_base const& other); + /** Disabled assignment operator. */ _inarray_common_base& operator=(_inarray_common_base const& other); }; +/** + * Optimized specialization of the base inline array for POD types. + */ template class _pod_inarray : _inarray_common_base { - typedef _inarray_common_base _base_type; + typedef _inarray_common_base _base_type; /**< Type for the base class. */ public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef T* pointer; - typedef T const* const_pointer; + typedef T value_type; /**< The type of each element. */ + typedef T& reference; /**< Type for a reference to an element. */ + typedef T const& const_reference; /**< Type for a constant reference to an element. */ + typedef T* pointer; /**< Type for a pointer to an element. */ + typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ + + /** + * Type for a iterator for this container. + * Defined as a @ref pointer for performance reasons. + */ typedef pointer iterator; + + /** + * Type for a constant iterator for this container. + * Defined as a @ref const_pointer for performance reasons. + */ typedef const_pointer const_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef _base_type::native_handle_type native_handle_type; - typedef _base_type::const_native_handle_type const_native_handle_type; + typedef std::size_t size_type; /**< Type for size information used in the array. */ + typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ + typedef _base_type::native_handle_type native_handle_type; /** Type for the native @c Eina_Inarray handle. */ + typedef _base_type::const_native_handle_type const_native_handle_type; /** Type for constant native @c Eina_Inarray handle. */ - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; /**< Type for reverse iterator of the array. */ + typedef std::reverse_iterator const_reverse_iterator; /** Type for constant reverse iterator of the array. */ - using _base_type::size; - using _base_type::empty; - using _base_type::native_handle; + using _base_type::size; /**< Type for size information used in the array. */ + /** + * @brief Check if the array is empty. + * @return @c true if the array is empty, @c false otherwise. + * + * This member function returns @c true if the array does not contain + * any elements, otherwise it returns @c false. + */ + using _base_type::empty; + using _base_type::native_handle; /** Type for the native @c Eina_Inarray handle. */ + + + /** + * @brief Create a new object from a handle to a native @c Eina_Inarray. + * @param array Handler to a native @c Eina_Inarray. + * + * This constructor wraps a pre-allocated @c Eina_Inarray providing an + * OOP interface to it. + * + * @warning It is important to note that the created object gains + * ownership of the handle, deallocating it at destruction time. + */ _pod_inarray(Eina_Inarray* array) : _base_type(array) {} + + /** + * @brief Default constructor. Create an empty array. + * + * This constructor creates an array object with no elements. Elements + * are declarated as having the same size of the given template + * typename argument. + */ _pod_inarray() : _base_type(sizeof(T)) { } + + /** + * @brief Construct an array object with @p n copies of @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + * + * This constructor creates an inline array with @p n elements, each + * one as a copy of @p t. + */ _pod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T)) { while(n--) push_back(t); } + + /** + * @brief Create a inline array with elements from the given range. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * + * This constructor creates a inline array with copies of the elements + * between @p i and @p j in the same order. + * + * @note The ending element (pointed by @p j) is not copied. + */ template _pod_inarray(InputIterator i, InputIterator const& j , typename eina::enable_if::value>::type* = 0) @@ -246,24 +552,58 @@ public: ++i; } } + + /** + * @brief Copy constructor. Creates a copy of the given inline array. + * @param other Another inline array of the same type. + * + * This constructor creates an inline array containing a copy of each + * element inside @p other in the same order. + */ _pod_inarray(_pod_inarrayconst& other) : _base_type(sizeof(T)) { insert(end(), other.begin(), other.end()); } + + /** + * Do nothing, the native @c Eina_Inarray is already released in the + * base class destructor. + */ ~_pod_inarray() { } + + /** + * @brief Replace the current content with the cotent of another array. + * @param other Another inline array of the same type. + * + * This assignment operator replaces the content of the array by a + * copy of the content of @p other. The array size is adjusted + * accordingly and the newly copied elements keep their original order. + */ _pod_inarray& operator=(_pod_inarrayconst& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } + + /** + * @brief Remove all the elements of the array. + */ void clear() { ::eina_inarray_flush(_array); } + + /** + * @brief Add a copy of the given element at the end of the array. + * @param value Element to be added at the end of the array. + * + * This member function allocates a new element at the end of the + * inline array, the content of @p value is copied to the new element. + */ void push_back(T const& value) { size_type s = size(); @@ -271,10 +611,28 @@ public: assert(size() != s); assert(size() == s + 1u); } + + /** + * @brief Remove the last element of the array. + */ void pop_back() { eina_inarray_pop(_array); } + + /** + * @brief Insert a new element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param t Value to be copied to the new element. + * @return Iterator pointing to the new element inserted. + * + * This member function inserts a copy of the element @p t at the + * position @p i. The new element comes right before the element + * originally pointed by @p i. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + */ iterator insert(iterator i, value_type const& t) { if(i != end()) @@ -290,6 +648,21 @@ public: return end()-1; } } + + /** + * @brief Insert @p n copies of @p t at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param t Value to be copied to each new inserted element. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts @p n new elements at position @p i + * in the array, each one as a copy of @p t. The new elements come + * right before the element originally pointed by @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ iterator insert(iterator i, size_t n, value_type const& t) { T* q; @@ -306,6 +679,22 @@ public: std::memcpy(p, &t, sizeof(t)); return q; } + + /** + * @brief Insert the elements between the given range at the given position. + * @param p Iterator pointing to the position where the new elements will be inserted. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts a copy of the elements between @p i + * and @p j at the position @p p. The new elements come right before + * the element originally pointed by @p p. Note that the element + * pointed by @p j is not copied. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ template iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -320,11 +709,35 @@ public: } return p - n; } + + /** + * @brief Remove the element at the given position. + * @param q Iterator pointing to the element to be removed. + * @return Iterator pointing to the element after the removed one. + * + * This member function removes the element pointed by the iterator + * @p q, reducing the array size by one. At the end, a valid iterator + * pointing to the element right after the removed one is returned. + */ iterator erase(iterator q) { ::eina_inarray_remove_at(_array, q - begin()); return q; } + + /** + * @brief Remove the elements between the given range. + * @param i Iterator pointing to the starting position to be removed. + * @param j Iterator pointing to the ending position to be removed. + * The element pointed by this iterator is not removed. + * @return Iterator pointing to the new position of the first + * non-removed element after the removed ones (i.e. the one + * originally pointed by @p j). + * + * This member function removes the elements between the iterators + * @p i and @p j, including the element pointed by @p i but not the + * element pointed by @j. + */ iterator erase(iterator i, iterator j) { while(i != j) @@ -333,92 +746,293 @@ public: } return i; } + + /** + * @brief Replace the content of the array by the elements in the given range. + * @param i Iterator pointing to the beginning of the elements to be copied. + * @param j Iterator pointing to the end of the elements to be copied. + * Note that the element pointed by j will NOT be copied. + * + * This member function replaces the current elements by copies of the + * elements between the iterators @p i and @p j, including the element + * pointed by @p i but not the one pointed by @p j. The size of the + * array is adjusted accordingly and the newly copied elements remain + * in their original order. + */ template void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0); + + /** + * @brief Replace the content of the array by @p n copies @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + */ void assign(size_type n, value_type const& t); + + /** + * @brief Get a reference to the element at the given position. + * @param i Position of the element. + * @return Reference to the element at the ith position. + */ value_type& operator[](size_type i) { return *(begin() + i); } + + /** + * @brief Get a constant reference to the element at the given position. + * @param i Position of the element. + * @return Constant reference to the element at the ith position. + * + * Version of @ref operator[](size_type i) for const-qualified inline + * array objects. Returns a constant reference instead. + */ value_type const& operator[](size_type i) const { return const_cast&>(*this)[i]; } + + /** + * @brief Get a reference to the last element. + * @return Reference to the last element in the array. + */ value_type& back() { return _inarray_access_traits::back(_array); } + + /** + * @brief Get a constant reference to the last element. + * @return Constant reference to the last element in the array. + * + * Version of @ref back() for const-qualified inline array objects. + * Returns a constant reference instead. + */ value_type const& back() const { return _inarray_access_traits::back(_array); } + + /** + * @brief Get a reference to the first element. + * @return Reference to the first element of the array. + */ value_type& front() { return _inarray_access_traits::front(_array); } + + /** + * @brief Get a constant reference to the first element. + * @return Constant reference to the first element of the array. + * + * Version of @ref front() for const-qualified inline array objects. + * Returns a constant reference instead. + */ value_type const& front() const { return _inarray_access_traits::front(_array); } + + /** + * @brief Get an iterator pointing to the first element of the array. + * @return Iterator to the initial position of the array. + * + * This member function returns an iterator pointing to the first + * element of the array. If the array is empty the returned iterator + * is the same as the one returned by @ref end(). + */ iterator begin() { return _inarray_access_traits::begin(_array); } + + /** + * @brief Get an iterator to the position following the last element of the array. + * @return Iterator to the final position of the array. + * + * This member function returns an iterator to the position following + * the last element in the array. If the array is empty the returned + * iterator is the same as the one returned by @ref begin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ iterator end() { return _inarray_access_traits::end(_array); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * Version of @ref begin() for const-qualified inline array objects. + * Returns a constant iterator instead. + */ const_iterator begin() const { return _inarray_access_traits::begin(_array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * Version of @ref end() for const-qualified inline array objects. + * Returns a constant iterator instead. + */ const_iterator end() const { return _inarray_access_traits::end(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * Version of @ref rbegin() for const-qualified inline array objects. + * Returns a constant reverse iterator instead. + */ const_reverse_iterator rbegin() const { return _inarray_access_traits::rbegin(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * Version of @ref rend() for const-qualified inline array objects. + * Returns a constant reverse iterator instead. + */ const_reverse_iterator rend() const { return _inarray_access_traits::rend(_array); } + + /** + * @brief Get a reverse iterator pointing to the reverse begin of the array. + * @return Reverse iterator pointing to the reverse begin of the array. + * + * This member function returns a reverse iterator pointing to the + * last element of the array. If the array is empty the returned + * reverse iterator is the same as the one returned by @ref rend(). + */ reverse_iterator rbegin() { return _inarray_access_traits::rbegin(_array); } + + /** + * @brief Get a reverse iterator pointing to the reverse end of the array. + * @return Reverse iterator pointing to the reverse end of the array. + * + * This member function returns a reverse iterator pointing to the + * position before the first element of the array. If the array is + * empty the returned iterator is the same as the one returned by + * @ref rbegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ reverse_iterator rend() { return _inarray_access_traits::rend(_array); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * This member function works like @ref begin() const but is granted + * to return a constant iterator even for arrays that are not + * const-qualified. + */ const_iterator cbegin() const { return _inarray_access_traits::cbegin(_array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * This member function works like @ref end() const but is granted to + * return a constant iterator even for arrays that are not + * const-qualified. + */ const_iterator cend() const { return _inarray_access_traits::cend(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * This member function works like @ref rbegin() const but is granted + * to return a constant reverse iterator even for arrays that are not + * const-qualified. + */ const_reverse_iterator crbegin() const { return _inarray_access_traits::crbegin(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * This member function works like @ref rend() const but is granted to + * return a constant reverse iterator even for arrays that are not + * const-qualified. + */ const_reverse_iterator crend() const { return _inarray_access_traits::crend(_array); } + + /** + * @brief Swap content between two inline arrays. + * @param other Other inline array of the same type. + */ void swap(_pod_inarray& other) { std::swap(_array, other._array); } + + /** + * @brief Get the maximum number of elements a inline array can hold. + * @return Maximum number of elements a inline array can hold. + */ size_type max_size() const { return -1; } + /** + * @brief Get a handle for the wrapped Eina_Inarray. + * @return Handle for the native Eina inline array. + * + * This member function returns the native Eina_Inarray handle that is + * wrapped inside this object. + * + * @warning It is important to take care when using it, since the + * handle will be automatically release upon object destruction. + */ Eina_Inarray* native_handle() { return this->_array; } + + /** + * @brief Get a constant handle for the wrapped Eina_Inarray. + * @return Constant handle for the native Eina inline array. + * + * Version of @ref native_handle() for const-qualified objects.Returns + * a constant handle instead. + * + * @see native_handle() + */ Eina_Inarray const* native_handle() const { return this->_array; @@ -428,34 +1042,81 @@ public: template class _nonpod_inarray : _inarray_common_base { - typedef _inarray_common_base _base_type; + typedef _inarray_common_base _base_type; /**< Type for the base class. */ public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef T* pointer; - typedef T const* const_pointer; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; + typedef T value_type; /**< The type of each element. */ + typedef T& reference; /**< Type for a reference to an element. */ + typedef T const& const_reference; /**< Type for a constant reference to an element. */ + typedef T* pointer; /**< Type for a pointer to an element. */ + typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + /** + * Type for a iterator to this kind of inline array. + * Defined as a @ref pointer for performance reasons. + */ + typedef pointer iterator; + + /** + * Type for a constant iterator for this kind of inline array. + * Defined as a @ref const_pointer for performance reasons. + */ + typedef const_pointer const_iterator; + typedef std::size_t size_type; /**< Type for size information used in the array. */ + typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ + + typedef std::reverse_iterator reverse_iterator; /** Type for the native @c Eina_Inarray handle. */ + typedef std::reverse_iterator const_reverse_iterator; /** Type for constant native @c Eina_Inarray handle. */ using _base_type::size; using _base_type::empty; + /** + * @brief Create a new object from a handle to a native Eina_Inarray. + * @param array Handle to a native Eina_Inarray. + * + * This constructor wraps a pre-allocated Eina_Inarray providing an + * OOP interface to it. + * + * @warning It is important to note that the created object gains + * ownership of the handle, deallocating it at destruction time. + */ _nonpod_inarray(Eina_Inarray* array) : _base_type(array) {} + + /** + * @brief Default constructor. Create an empty array. + * + * This constructor creates an array object with no elements. Elements + * are declarated as having the same size of the given template + * typename argument. + */ _nonpod_inarray() : _base_type(sizeof(T)) { } + + /** + * @brief Construct an array object with @p n copies of @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + * + * This constructor creates an inline array with @p n elements, each + * one as a copy of @p t. + */ _nonpod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T)) { while(n--) push_back(t); } + + /** + * @brief Create a inline array coping the elements from the given range. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * + * This constructor creates a inline array with copies of the elements + * between @p i and @p j in the same order. Note that the ending + * element (pointed by @p j) is excluded. + */ template _nonpod_inarray(InputIterator i, InputIterator const& j , typename eina::enable_if::value>::type* = 0) @@ -467,23 +1128,52 @@ public: ++i; } } + + /** + * @brief Copy constructor. Creates a copy of the given inline array. + * @param other Another inline array of the same type. + * + * This constructor creates an inline array containing a copy of each + * element inside @p other in the same order. + */ _nonpod_inarray(_nonpod_inarrayconst& other) : _base_type(sizeof(T)) { insert(end(), other.begin(), other.end()); } + + /** + * @brief Destructor of array for non-POD elements. + * + * Calls the destructor of each allocated element, before the base + * class destructor releases their memory. + */ ~_nonpod_inarray() { for(T* first = static_cast(_array->members) , *last = first + _array->len; first != last; ++first) first->~T(); } + + /** + * @brief Replace current content with the cotent of another array. + * @param other Another inline array of the same type. + * + * This assignment operator replaces the content of the array by a + * copy of the content of the given array @p other. The array size is + * adjusted accordingly and the newly copied elements keep their + * original order. + */ _nonpod_inarray& operator=(_nonpod_inarrayconst& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } + + /** + * @brief Remove all the elements of the array. + */ void clear() { for(T* first = static_cast(_array->members) @@ -491,20 +1181,61 @@ public: first->~T(); ::eina_inarray_flush(_array); } + + /** + * @brief Add a copy of the given element at the end of the array. + * @param value Element to be added at the end of the array. + * + * This member function allocates a new element at the end of the + * inline array, the content of @p value is copied to the new element. + */ void push_back(T const& value) { insert(end(), 1u, value); } + + /** + * @brief Remove the last element of the array. + */ void pop_back() { T* elem = static_cast(_array->members) + _array->len - 1; elem->~T(); eina_inarray_pop(_array); } + + /** + * @brief Insert a new element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param t Value to be copied to the new element. + * @return Iterator pointing to the new element inserted. + * + * This member function inserts a copy of the element @p t at the + * position @p i. The new element comes right before the element + * originally pointed by @p i. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + */ iterator insert(iterator i, value_type const& t) { return insert(i, 1u, t); } + + /** + * @brief Insert @p n copies of @p t at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param t Value to be copied to each new inserted element. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts @p n new elements at position @p i + * in the array, each one as a copy of @p t. The new elements come + * right before the element originally pointed by @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ iterator insert(iterator i, size_t n, value_type const& t) { if(_array->max - _array->len >= n) @@ -546,7 +1277,7 @@ public: , first = begin() , last = first + _array->len; i = index + begin(); - + while(first != i) { new (&*first++) T(*old_first); @@ -565,6 +1296,19 @@ public: } return i; } + + /** + * @brief Insert the elements between the given range at the given position. + * @param p Iterator pointing to the position where the new elements will be inserted. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts a copy of the elements between @p i + * and @p j at the position @p p. The new elements come right before + * the element originally pointed by @p p. Note that the element + * pointed by @p j is not copied. + */ template iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -579,10 +1323,34 @@ public: } return p - n; } + + /** + * @brief Remove the element at the given position. + * @param q Iterator pointing to the element to be removed. + * @return Iterator pointing to the element after the removed one. + * + * This member function removes the element pointed by the iterator + * @p q, reducing the array size by one. At the end, a valid iterator + * pointing to the element right after the removed one is returned. + */ iterator erase(iterator q) { return erase(q, q+1); } + + /** + * @brief Remove the elements between the given range. + * @param i Iterator pointing to the starting position to be removed. + * @param j Iterator pointing to the ending position to be removed. + * The element pointed by this iterator is not removed. + * @return Iterator pointing to the new position of the first + * non-removed element after the removed ones (i.e. the one + * originally pointed by j). + * + * This member function removes the elements between the iterators + * @p i and @p j, including the element pointed by @p i but not the + * element pointed by @j. + */ iterator erase(iterator i, iterator j) { iterator last = end(); @@ -595,118 +1363,373 @@ public: return i; } + + /** + * @brief Replace the content of the array by the elements in the given range. + * @param i Iterator pointing to the beginning of the elements to be copied. + * @param j Iterator pointing to the end of the elements to be copied. + * Note that the element pointed by j will NOT be copied. + * + * This member function replaces the current elements by copies of the + * elements between the iterators @p i and @p j, including the element + * pointed by @p i but not the one pointed by @p j. The size of the + * array is adjusted accordingly and the newly copied elements remain + * in their original order. + */ template void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0); + + /** + * @brief Replace the content of the array by @p n copies @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + */ void assign(size_type n, value_type const& t); + + /** + * @brief Get a reference to the element at the given position. + * @param i Position of the element. + * @return Reference to the element at the ith position. + */ value_type& operator[](size_type i) { return *(begin() + i); } + + + /** + * @brief Get a constant reference to the element at the given position. + * @param i Position of the element. + * @return Constant reference to the element at the ith position. + * + * Version of @ref operator[](size_type i) for const-qualified inline + * array objects. Return a constant reference instead. + */ value_type const& operator[](size_type i) const { return const_cast&>(*this)[i]; } + + /** + * @brief Get a reference to the last element. + * @return Reference to the last element in the array. + */ value_type& back() { return _inarray_access_traits::back(_array); } + + /** + * @brief Get a constant reference to the last element. + * @return Constant reference to the last element in the array. + * + * Version of @ref back() for const-qualified inline array objects. + * Return a constant reference instead. + */ value_type const& back() const { return _inarray_access_traits::back(_array); } + + /** + * @brief Get a reference to the first element. + * @return Reference to the first element of the array. + */ value_type& front() { return _inarray_access_traits::front(_array); } + + /** + * @brief Get a constant reference to the first element. + * @return Constant reference to the first element of the array. + * + * Version of @ref front() for const-qualified inline array objects. + * Return a constant reference instead. + */ value_type const& front() const { return _inarray_access_traits::front(_array); } + + /** + * @brief Get an iterator pointing to the first element of the array. + * @return Iterator to the initial position of the array. + * + * This member function returns an iterator pointing to the first + * element of the array. If the array is empty the returned iterator + * is the same as the one returned by @ref end(). + */ iterator begin() { return _inarray_access_traits::begin(_array); } + + /** + * @brief Get an iterator to the position following the last element of the array. + * @return Iterator to the final position of the array. + * + * This member function returns an iterator to the position following + * the last element in the array. If the array is empty the returned + * iterator is the same as the one returned by @ref begin(). + * Note that attempting to access this position causes undefined + * behavior. + */ iterator end() { return _inarray_access_traits::end(_array); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * Version of @ref begin() for const-qualified inline array objects. + * Returns a constant iterator instead. + */ const_iterator begin() const { return _inarray_access_traits::begin(_array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * Version of @ref end() for const-qualified inline array objects. + * Returns a constant iterator instead. + */ const_iterator end() const { return _inarray_access_traits::end(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * Version of @ref rbegin() for const-qualified inline array objects. + * Returns a constant reverse iterator instead. + */ const_reverse_iterator rbegin() const { return _inarray_access_traits::rbegin(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * Version of @ref rend() for const-qualified inline array objects. + * Returns a constant reverse iterator instead. + */ const_reverse_iterator rend() const { return _inarray_access_traits::rend(_array); } + + /** + * @brief Get a reverse iterator pointing to the reverse begin of the array. + * @return Reverse iterator pointing to the reverse begin of the array. + * + * This member function returns a reverse iterator pointing to the + * last element of the array. If the array is empty the returned + * reverse iterator is the same as the one returned by @ref rend(). + */ reverse_iterator rbegin() { return _inarray_access_traits::rbegin(_array); } + + /** + * @brief Get a reverse iterator pointing to the reverse end of the array. + * @return Reverse iterator pointing to the reverse end of the array. + * + * This member function returns a reverse iterator pointing to the + * position before the first element of the array. If the array is + * empty the returned iterator is the same as the one returned by + * @ref rbegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ reverse_iterator rend() { return _inarray_access_traits::rend(_array); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * This member function works like the constant overload of @ref begin() + * but is granted to return a constant iterator even for arrays that + * are not const-qualified. + */ const_iterator cbegin() const { return _inarray_access_traits::cbegin(_array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * This member function works like the constant overload of @ref end() + * but is granted to return a constant iterator even for arrays that + * are not const-qualified. + */ const_iterator cend() const { return _inarray_access_traits::cend(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * This member function works like the constant overload of @ref rbegin() + * but is granted to return a constant reverse iterator even for + * arrays that are not const-qualified. + */ const_reverse_iterator crbegin() const { return _inarray_access_traits::crbegin(_array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * This member function works like the constant overload of @ref rend() + * but is granted to return a constant reverse iterator even for + * arrays that are not const-qualified. + */ const_reverse_iterator crend() const { return _inarray_access_traits::crend(_array); } + + /** + * @brief Swap content between two inline arrays. + * @param other Other inline array of the same type. + */ void swap(_nonpod_inarray& other) { std::swap(_array, other._array); } + + /** + * @brief Get the maximum number of elements a inline array can hold. + * @return Maximum number of elements a inline array can hold. + */ size_type max_size() const { return -1; } + /** + * @brief Get the handle for the wrapped Eina_Inarray. + * @return Internal handle for the native Eina inline array. + * + * This member function returns the native Eina_Inarray handle that is + * wrapped inside this object. It is important to take care when using + * it, since the handle will be automatically release upon object + * destruction. + */ Eina_Inarray* native_handle() { return this->_array; } + + /** + * @brief Get the handle for the wrapped Eina_Inarray. + * @return Internal handle for the native Eina inline array. + * + * This member function returns the native Eina_Inarray handle that is + * wrapped inside this object. It is important to take care when using + * it, since the handle will be automatically release upon object + * destruction. + */ Eina_Inarray const* native_handle() const { return this->_array; } }; + +/** + * Inline array class. It provides an OOP interface to the + * @c Eina_Inarray functions, and automatically take care of allocating + * and deallocating resources using the RAII programming idiom. + * + * It also provides additional member functions to facilitate the access + * to the array content, much like a STL vector. + */ template class inarray : public eina::if_, _pod_inarray , _nonpod_inarray >::type { typedef typename eina::if_, _pod_inarray - , _nonpod_inarray >::type _base_type; + , _nonpod_inarray >::type _base_type; /**< Type for the base class. */ public: + + /** + * @brief Create a new object from a handle to a native Eina_Inarray. + * @param array Handle to a native Eina_Inarray. + * + * This constructor wraps a pre-allocated Eina_Inarray providing an + * OOP interface to it. + * + * @warning It is important to note that the created object gains + * ownership of the handle, deallocating it at destruction time. + */ inarray(Eina_Inarray* array) : _base_type(array) {} + + /** + * @brief Default constructor. Creates an empty array. + */ inarray() : _base_type() {} + + /** + * @brief Construct an array object with @p n copies of @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + * + * This constructor creates an inline array with @p n elements, each + * one as a copy of @p t. + */ inarray(typename _base_type::size_type n, typename _base_type::value_type const& t) : _base_type(n, t) {} + + /** + * @brief Create a inline array with elements from the given range. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * + * This constructor creates a inline array with copies of the elements + * between @p i and @p j in the same order. + * + * @note The ending element (pointed by @p j) is not copied. + */ template inarray(InputIterator i, InputIterator const& j , typename eina::enable_if::value>::type* = 0) : _base_type(i, j) {} - + }; +/** + * @brief Check if two inline arrays are equal. + * @param lhs Inline array at the left side of the expression. + * @param rhs Inline array at the right side of the expression. + * @return @c true if the arrays are equals, @c false otherwise. + * + * This operator checks if the given inline arrays are equal. To be + * considered equal both arrays need to have the same number of + * elements, and each element in one array must be equal to the element + * at the same position in the other array. + */ template bool operator==(inarray const& lhs, inarray const& rhs) { @@ -714,19 +1737,38 @@ bool operator==(inarray const& lhs, inarray const& rhs) std::equal(lhs.begin(), lhs.end(), rhs.begin()); } +/** + * @brief Check if two inline arrays are different. + * @param lhs Inline array at the left side of the expression. + * @param rhs Inline array at the right side of the expression. + * @return @c true if the arrays are not equal , @c false otherwise. + * + * This operator returns the opposite of @ref operator==(inarray const& lhs, inarray const& rhs). + */ template bool operator!=(inarray const& lhs, inarray const& rhs) { return !(lhs == rhs); } +/** + * @brief Swap content between two inline arrays. + * @param other Other inline array of the same type. + */ template void swap(inarray& lhs, inarray& rhs) { lhs.swap(rhs); } +/** + * @} + */ } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_inlist.hh b/src/bindings/eina_cxx/eina_inlist.hh index 7fdf166390..4d83632c0b 100644 --- a/src/bindings/eina_cxx/eina_inlist.hh +++ b/src/bindings/eina_cxx/eina_inlist.hh @@ -10,8 +10,24 @@ #include #include +/** + * @addtogroup Eina_Cxx_Containers_Group + * + * @{ + */ + namespace efl { namespace eina { +/** + * @defgroup Eina_Cxx_Inline_List_Group Inline List + * @ingroup Eina_Cxx_Containers_Group + * + * @{ + */ + +/** + * @internal + */ template struct _inlist_node { @@ -19,18 +35,27 @@ struct _inlist_node T object; }; +/** + * @internal + */ template _inlist_node* _get_node(Eina_Inlist* l) { return static_cast<_inlist_node*>(static_cast(l)); } +/** + * @internal + */ template _inlist_node const* _get_node(Eina_Inlist const* l) { return const_cast(l); } +/** + * @internal + */ template Eina_Inlist* _get_list(_inlist_node* n) { @@ -40,38 +65,85 @@ Eina_Inlist* _get_list(_inlist_node* n) return 0; } +/** + * @internal + */ template Eina_Inlist const* _get_list(_inlist_node const* n) { return _get_list(const_cast<_inlist_node*>(n)); } +/** + * @internal + * Iterator for Inline List + */ template struct _inlist_iterator { - typedef typename std::remove_const::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::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* list, _inlist_node* node) : _list(list), _node(node) {} + + /** + * @brief Copy constructor. Creates a copy of the given iterator. + * @param other Other iterator. + */ _inlist_iterator(_inlist_iterator::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& operator++() { _node = _get_node(_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 operator++(int) { _inlist_iterator 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& operator--() { if(_node) @@ -80,32 +152,65 @@ struct _inlist_iterator _node = _get_node(_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 operator--(int) { _inlist_iterator 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* native_handle() { return _node; } + + /** + * @internal + */ _inlist_node const* native_handle() const { return _node; } private: - _inlist_node* _list; - _inlist_node* _node; + _inlist_node* _list; /**< Handle to the original list. */ + _inlist_node* _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 friend struct _inlist_iterator; friend bool operator==(_inlist_iterator lhs, _inlist_iterator 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 bool operator!=(_inlist_iterator lhs, _inlist_iterator rhs) { return !(lhs == rhs); } +/** + * @internal + */ struct _inlist_access_traits { template struct const_iterator @@ -242,49 +356,93 @@ struct _inlist_access_traits { template class inlist; +/** + * @ingroup Eina_Cxx_Range_Group + * + * Range for inline list elements. + */ template struct range_inlist : _range_template { - typedef _range_template _base_type; - typedef typename _base_type::value_type value_type; - typedef typename _base_type::native_handle_type native_handle_type; + typedef _range_template _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 range_inlist(inlist& 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 bool operator==(range_inlistconst& lhs, range_inlistconst& rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } +/** + * @brief Returns the opposite of @ref operator==(range_inlistconst& lhs, range_inlistconst& rhs). + */ template bool operator!=(range_inlist const& lhs, range_inlistconst& rhs) { return !(lhs == rhs); } +/** + * Common implementations for inline list. + */ template struct _inlist_common_base { - typedef typename Allocator::template rebind<_inlist_node >::other node_allocator_type; - typedef Allocator allocator_type; - typedef _inlist_node node_type; + typedef typename Allocator::template rebind<_inlist_node >::other node_allocator_type; /**< Type for the allocator of the node. */ + typedef Allocator allocator_type; /**< Type for the allocator. */ + typedef _inlist_node 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 > class inlist : protected _inlist_common_base { - typedef _inlist_common_base _base_type; - typedef typename _base_type::node_type _node_type; + typedef _inlist_common_base _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 const_iterator; - typedef _inlist_iterator 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 const_iterator; /**< Type for constant iterator for this kind of container. */ + typedef _inlist_iterator 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 reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this kind of container. */ + typedef std::reverse_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 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(inlistconst& 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& operator=(inlistconst& 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(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(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 iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::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 void assign(InputIterator i, InputIterator j , typename eina::enable_if::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(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(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(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(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(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(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(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(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& 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 eina::accessor to the list. + * + * Version of @ref accessor() to const-qualified inline lists. Returns + * a const-qualified eina::accessor instead. + */ eina::accessor accessor() const { return eina::accessor(eina_inlist_accessor_new(this->_impl._list)); } + + /** + * @brief Get a @ref eina::accessor for the list. + * @return eina::accessor to the list. + */ eina::accessor accessor() { return eina::accessor(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 bool operator==(inlist const& lhs, inlist const& rhs) { @@ -601,18 +1138,33 @@ bool operator==(inlist const& lhs, inlist const& r std::equal(lhs.begin(), lhs.end(), rhs.begin()); } +/** + * @brief Return the opposite of @ref operator==(inlist const& lhs, inlist const& rhs). + */ template bool operator!=(inlist const& lhs, inlist const& rhs) { return !(lhs == rhs); } +/** + * @brief Swap content between two inline lists. + * @param other Other inline list of the same type. + */ template void swap(inlist& lhs, inlist& rhs) { lhs.swap(rhs); } +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_integer_sequence.hh b/src/bindings/eina_cxx/eina_integer_sequence.hh index 4ec17621f7..b1f98a0efa 100644 --- a/src/bindings/eina_cxx/eina_integer_sequence.hh +++ b/src/bindings/eina_cxx/eina_integer_sequence.hh @@ -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 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 std::size_t representing the sequence size. + */ static constexpr std::size_t size() { return sizeof...(Ints); } - typedef integer_sequence type; + typedef integer_sequence type; /**< Type for the sequence instantiation. */ }; template struct concat; +/** + * Compile-time concatenation of two integer sequences. + */ template struct concat, integer_sequence > : integer_sequence {}; @@ -21,6 +45,10 @@ template using Concat = typename concat::type; template struct gen_seq; + +/** + * Make a compile time sequence of integers from @c 0 to N-1. + */ template using make_integer_sequence = typename gen_seq::type; template @@ -30,12 +58,26 @@ struct gen_seq : Concat template<> struct gen_seq : integer_sequence{}; template<> struct gen_seq : integer_sequence{}; +/** + * Compile time sequence of indexes. + */ template using index_sequence = integer_sequence; +/** + * Make a compile time sequence of indexes from @c 0 to N-1. + */ template using make_index_sequence = make_integer_sequence; +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_iterator.hh b/src/bindings/eina_cxx/eina_iterator.hh index d10401c0c0..d291e8eaa8 100644 --- a/src/bindings/eina_cxx/eina_iterator.hh +++ b/src/bindings/eina_cxx/eina_iterator.hh @@ -6,33 +6,86 @@ #include #include +/** + * @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 struct _common_iterator_base { private: - typedef _common_iterator_base self_type; + typedef _common_iterator_base 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 const& lhs, _common_iterator_base 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 const& lhs, _common_iterator_base 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 struct iterator : _common_iterator_base { private: - typedef _common_iterator_base base_type; - typename base_type::pointer _value; - typedef iterator self_type; + typedef _common_iterator_base base_type; /**< Type for the base class. */ + typename base_type::pointer _value; /**< @internal */ + typedef iterator 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(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 diff --git a/src/bindings/eina_cxx/eina_lists_auxiliary.hh b/src/bindings/eina_cxx/eina_lists_auxiliary.hh index ebcbfd6016..924dd73306 100644 --- a/src/bindings/eina_cxx/eina_lists_auxiliary.hh +++ b/src/bindings/eina_cxx/eina_lists_auxiliary.hh @@ -3,8 +3,17 @@ #include +/** + * @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 diff --git a/src/bindings/eina_cxx/eina_log.hh b/src/bindings/eina_cxx/eina_log.hh index 87bcdb1257..77e30e56f1 100644 --- a/src/bindings/eina_cxx/eina_log.hh +++ b/src/bindings/eina_cxx/eina_log.hh @@ -3,39 +3,102 @@ #include +/** + * @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 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(*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 { 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 { 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 { + /** + * @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 diff --git a/src/bindings/eina_cxx/eina_optional.hh b/src/bindings/eina_cxx/eina_optional.hh index e6d853f1bb..2517412ebf 100644 --- a/src/bindings/eina_cxx/eina_optional.hh +++ b/src/bindings/eina_cxx/eina_optional.hh @@ -5,8 +5,17 @@ #include #include +/** + * @addtogroup Eina_Cxx_Data_Types_Group + * + * @{ + */ + namespace efl_eina_swap_adl { +/** + * @internal + */ template 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 void adl_swap(T& lhs, T& rhs) { ::efl_eina_swap_adl::swap_impl(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 + * std::pair, 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 struct optional { - typedef optional _self_type; + typedef optional _self_type; /**< Type for the optional class itself. */ + /** + * @brief Create a disengaged object. + * + * This constructor creates a disengaged eina::optional + * 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 eina::optional 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 eina::optional 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 eina::optional object that holds the same value type. + * + * This constructor creates an eina::optional 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 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 eina::optional object that holds the same value type. + * + * This constructor creates an eina::optional 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&& 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 eina::optional 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 *this be considered engaged too. If @p other is + * disengaged *this is also made disengaged and its + * contained value, if any, is simple destroyed. + */ _self_type& operator=(optional&& 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 eina::optional 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 *this be considered engaged too. If @p other is + * disengaged *this is also made disengaged and its + * contained value, if any, is simple destroyed. + */ _self_type& operator=(optionalconst& other) { optional 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(static_cast(&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 eina::optional object. + * @param other Another eina::optional object. + */ void swap(optional& 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 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 ::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 eina::optional object. + * + */ template void swap(optional& lhs, optional& rhs) { lhs.swap(rhs); } +/** + * @brief Check if both eina::optional object are equal. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional 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 bool operator==(optional const& lhs, optional const& rhs) { @@ -161,11 +337,28 @@ bool operator==(optional const& lhs, optional const& rhs) else return *lhs == *rhs; } + +/** + * @brief Check if the eina::optional objects are different. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional object at the right side of the expression. + * @return The opposite of @ref operator==(optional const& lhs, optional const& rhs). + */ template bool operator!=(optional const& lhs, optional const& rhs) { return !(lhs == rhs); } + +/** + * @brief Less than comparison between eina::optional objects. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional 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 bool operator<(optional const& lhs, optional const& rhs) { @@ -178,22 +371,60 @@ bool operator<(optional const& lhs, optional const& rhs) else return *lhs < *rhs; } + +/** + * @brief Less than or equal comparison between eina::optional objects. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional 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 bool operator<=(optional const& lhs, optional const& rhs) { return lhs < rhs || lhs == rhs; } + +/** + * @brief More than comparison between eina::optional objects. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional 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 bool operator>(optional const& lhs, optional const& rhs) { return !(lhs <= rhs); } + +/** + * @brief More than or equal comparison between eina::optional objects. + * @param lhs eina::optional object at the left side of the expression. + * @param rhs eina::optional 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 bool operator>=(optional const& lhs, optional const& rhs) { return !(lhs < rhs); } +/** + * @} + */ + } } // efl::eina +/** + * @} + */ + #endif // EINA_OPTIONAL_HH_ diff --git a/src/bindings/eina_cxx/eina_ptrarray.hh b/src/bindings/eina_cxx/eina_ptrarray.hh index 561c83ea3b..aec255c20f 100644 --- a/src/bindings/eina_cxx/eina_ptrarray.hh +++ b/src/bindings/eina_cxx/eina_ptrarray.hh @@ -11,8 +11,24 @@ #include #include +/** + * @addtogroup Eina_Cxx_Containers_Group + * + * @{ + */ + namespace efl { namespace eina { +/** + * @defgroup Eina_Cxx_Pointer_Array_Group Array of Pointers + * @ingroup Eina_Cxx_Containers_Group + * + * @{ + */ + +/** + * @internal + */ template struct _ptr_array_iterator { @@ -98,6 +114,9 @@ private: void** _ptr; }; +/** + * @internal + */ struct _ptr_array_access_traits { template @@ -245,6 +264,8 @@ static eina::iterator ciend(Eina_Array const* array) { return _ptr_array_access_traits::iend(array); } + + template static std::size_t size(Eina_Array const* array) { @@ -261,55 +282,121 @@ static bool empty(Eina_Array const* array) template class ptr_array; +/** + * @ingroup Eina_Cxx_Range_Group + * + * Range for @ref ptr_array. + */ template struct range_ptr_array : _range_template { - typedef _range_template _base_type; - typedef typename _base_type::value_type value_type; + typedef _range_template _base_type; /**< Type for the base class. */ + typedef typename _base_type::value_type value_type; /**< The type of each element. */ + /** + * @brief Creates a range from a native Eina array handle. + */ range_ptr_array(Eina_Array* array) : _base_type(array) {} + + /** + * @brief Creates a range from a @c ptr_array object. + */ template range_ptr_array(ptr_array& array) : _base_type(array.native_handle()) {} + + /** + * @brief Get the element at the given position in the array. + * @param index Position of the element. + * @return Reference to the element at the given position. + */ value_type& operator[](std::size_t index) const { return _ptr_array_access_traits::index(this->native_handle(), index); } }; +/** + * Common implementations for the ptr_array. + */ template struct _ptr_array_common_base { - typedef CloneAllocator clone_allocator_type; + typedef CloneAllocator clone_allocator_type; /**< Type for the clone allocator. */ + /** + * @brief Creates an array with the given clone allocator. + */ _ptr_array_common_base(CloneAllocator clone_allocator) : _impl(clone_allocator) {} + + /** + * @brief Create a new object from a handle to a native Eina_Array. + * @param array Handle to a native Eina_Array. + * + * This constructor wraps a pre-allocated Eina_Array providing an OOP + * interface to it. + * + * @warning It is important to note that the created object gains + * ownership of the handle, deallocating it at destruction time. + */ _ptr_array_common_base(Eina_Array* _array) : _impl(_array) {} + + /** + * @brief Default constructor. Create an empty array. + * + * This constructor creates an array with no elements. + */ _ptr_array_common_base() {} + /** + * @internal + * @brief Get the clone allocator of the array. + * @return Reference to the clone allocator. + */ CloneAllocator& _get_clone_allocator() { return _impl; } + + /** + * @internal + * @brief Get the clone allocator of the array. + * @return Constant reference to the clone allocator. + * + * Version of @ref _get_clone_allocator() for const-qualified arrays, + * returns a constant reference instead. + */ CloneAllocator const& _get_clone_allocator() const { return _impl; } + + /** + * @internal + */ void _delete_clone(T const* p) { _get_clone_allocator().deallocate_clone(p); } + + /** + * @internal + */ T* _new_clone(T const& a) { return _get_clone_allocator().allocate_clone(a); } + /** + * @internal + */ struct _ptr_array_impl : CloneAllocator { _ptr_array_impl() : _array( ::eina_array_new(32u) ) {} @@ -317,40 +404,79 @@ struct _ptr_array_common_base : clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {} Eina_Array* _array; - }; + }; + /** + * @internal + */ _ptr_array_impl _impl; private: + /** Disabled copy constructor. */ _ptr_array_common_base(_ptr_array_common_base const& other); + /** Disabled assignment operator. */ _ptr_array_common_base& operator=(_ptr_array_common_base const& other); }; +/** + * Array class. It provides an OOP interface to the @c Eina_Array + * functions, and automatically take care of allocating and deallocating + * resources using the RAII programming idiom. + * + * It also provides additional member functions to facilitate the access + * to the array content, much like a STL vector. + */ template class ptr_array : protected _ptr_array_common_base { - typedef _ptr_array_common_base _base_type; + typedef _ptr_array_common_base _base_type; /**< Type for the base class. */ public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef _ptr_array_iterator const_iterator; - typedef _ptr_array_iterator iterator; - typedef T* pointer; - typedef T const* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef CloneAllocator clone_allocator_type; + typedef T value_type; /**< The type of each element. */ + typedef T& reference; /**< Type for a reference to an element. */ + typedef T const& const_reference; /**< Type for a constant reference to an element. */ + typedef _ptr_array_iterator const_iterator; /**< Type for a iterator for this container. */ + typedef _ptr_array_iterator iterator; /**< Type for a constant iterator for this container. */ + typedef T* pointer; /**< Type for a pointer to an element. */ + typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ + typedef std::size_t size_type; /**< Type for size information used in the array. */ + typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ + typedef CloneAllocator clone_allocator_type; /** Type for the clone allocator. */ - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ + typedef std::reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ + /** + * @brief Default constructor. Create an empty array. + * + * This constructor creates a @c ptr_array object with no elements. + */ ptr_array() {} + + /** + * @brief Construct an array object with @p n copies of @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + * + * This constructor creates a @c ptr_array with @p n elements, each + * one as a copy of @p t. + */ ptr_array(size_type n, const_reference t) { while(n--) push_back(t); } + + /** + * @brief Create an array with elements from the given range. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @param alloc Clone allocator to be used. + * + * This constructor creates a @c ptr_array with copies of the elements + * between @p i and @p j in the same order. + * + * @note The ending element (pointed by @p j) is not copied. + */ template ptr_array(InputIterator i, InputIterator const& j , clone_allocator_type const& alloc = clone_allocator_type() @@ -363,55 +489,142 @@ public: ++i; } } + + /** + * @brief Copy constructor. Creates a copy of the given @c ptr_array. + * @param other Another @c ptr_array of the same type. + * + * This constructor creates a @c ptr_array containing a copy of each + * element inside @p other in the same order. + */ ptr_array(ptr_array const& other) : _base_type() { insert(end(), other.begin(), other.end()); } + + /** + * @brief Creates a copy of a @c ptr_array with a different clone allocator. + * @param other Another @c ptr_array with a different clone allocator. + * + * This constructor creates a @c ptr_array containing a copy of each + * element inside @p other in the same order, even if the given array + * uses a different clone allocator. + */ template ptr_array(ptr_arrayconst& other) : _base_type() { insert(end(), other.begin(), other.end()); } + + /** + * @brief Destructor. Release all allocated elements. + */ ~ptr_array() { clear(); } + + /** + * @brief Replace the current content with the content of another array. + * @param other Another @c ptr_array of the same type. + * + * This assignment operator replaces the content of the array by a + * copy of the content of @p other. The array size is adjusted + * accordingly and the newly copied elements keep their original order. + */ ptr_array& operator=(ptr_arrayconst& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } - + + /** + * @brief Remove all the elements of the array. + */ void clear() { for(iterator first = begin(), last = end(); first != last; ++first) this->_delete_clone(&*first); eina_array_flush(this->_impl._array); } + + /** + * @brief Get the current size of the array. + * @return Number of elements in the array. + * + * This member function returns the current number of elements inside + * the array. + */ std::size_t size() const { return eina_array_count(this->_impl._array); } + + /** + * @brief Check if the array is empty. + * @return @c true if the array is empty, @c false otherwise. + * + * This member function returns @c true if the array does not contain + * any elements, otherwise it returns @c false. + */ bool empty() const { return size() == 0u; } + + /** + * @brief Get the clone allocator of the array. + * @return Reference to the clone allocator. + */ clone_allocator_type get_clone_allocator() const { return clone_allocator_type(this->_get_clone_allocator()); } + + /** + * @brief Add a copy of the given element at the end of the array. + * @param a Element to be added at the end of the array. + * + * This member function allocates a new element, as a copy of @p a, + * and inserts it at the end of the array. + */ void push_back(const_reference a) { push_back(this->_new_clone(a)); } + + /** + * @brief Add the object pointed by @p p as a element at the end of the array. + * @param p Pointer to a pre-allocated element to be inserted at the end of the array. + * + * This member function adds the object pointed by @p p as a element + * at the end of the array. The array gains ownership of the pointer + * and nothing is copied. + * + * @warning The array gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ void push_back(pointer p) { std::unique_ptr p1(p); push_back(p1); } + + + /** + * @brief Add the object pointed by @p p as a element at the end of the array. + * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the end of the array. + * + * This member function adds the object pointed by the given + * @c unique_ptr as a element at the end of the array. The object + * ownership is transferred to the array and nothing is copied. + * + * @warning The array gains ownership of the object managed by the + * given @c unique_ptr and will release it upon element destruction. + */ void push_back(std::unique_ptr& p) { if(eina_array_push(this->_impl._array, p.get())) @@ -419,19 +632,73 @@ public: else throw std::bad_alloc(); } + + /** + * @brief Remove the last element of the array. + */ void pop_back() { eina_array_pop(this->_impl._array); } + + /** + * @brief Insert a copy of the given element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param t Value to be copied to the new element. + * @return Iterator pointing to the new element inserted. + * + * This member function inserts a copy of the element @p t at the + * position @p i. The new element comes right before the element + * originally pointed by @p i. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + */ iterator insert(iterator i, value_type const& t) { return insert(i, this->_new_clone(t)); - } + } + + /** + * @brief Insert the object pointed by @p pv as a element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param pv Pointer to a pre-allocated object to be inserted to the array. + * @return Iterator pointing to the new element inserted. + * + * This member function adds the object pointed by @p pv as a element + * at the given position. The new element comes right before the + * element originally pointed by @p i. The array gains ownership of + * the pointer and nothing is copied. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + * + * @warning The array gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ iterator insert(iterator i, pointer pv) { std::unique_ptr p(pv); return insert(i, p); } + + /** + * @brief Insert the object pointed by @p p as a element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param p Reference to a @c unique_ptr pointing to the element to be inserted in the array. + * @return Iterator pointing to the new element inserted. + * + * This member function adds the object pointed by @p p as a element + * at the given position. The new element comes right before the + * element originally pointed by @p i. The object ownership is + * transferred to the array and nothing is copied. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + * + * @warning The array gains ownership of the object managed by the + * given @c unique_ptr and will release it upon element destruction. + */ iterator insert(iterator i, std::unique_ptr& p) { std::size_t j @@ -455,7 +722,22 @@ public: } else throw std::bad_alloc(); - } + } + + /** + * @brief Insert @p n copies of @p t at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param t Value to be copied to each new inserted element. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts @p n new elements at position @p i + * in the array, each one as a copy of @p t. The new elements come + * right before the element originally pointed by @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ iterator insert(iterator i, size_t n, value_type const& t) { iterator r = i; @@ -465,6 +747,25 @@ public: insert(i, t); return r; } + + /** + * @brief Insert the object pointed by @p p and n-1 copies of it as elements at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param p Pointer to a pre-allocated object to be inserted in the array. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts the object pointed by @p p and + * n-1 copies of it as elements at the given position. The + * new elements come right before the element originally pointed by + * @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + * + * @warning The array gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ iterator insert(iterator i, size_t n, pointer p) { iterator r = i; @@ -474,6 +775,22 @@ public: insert(i, this->_new_clone(p)); return r; } + + /** + * @brief Insert the elements between the given range at the given position. + * @param p Iterator pointing to the position where the new elements will be inserted. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts a copy of the elements between @p i + * and @p j at the position @p p. The new elements come right before + * the element originally pointed by @p p. Note that the element + * pointed by @p j is not copied. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ template iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -487,6 +804,16 @@ public: } return iterator(this->_impl._array->data + index); } + + /** + * @brief Remove the element at the given position. + * @param q Iterator pointing to the element to be removed. + * @return Iterator pointing to the element after the removed one. + * + * This member function removes the element pointed by the iterator + * @p q, reducing the array size by one. At the end, a valid iterator + * pointing to the element right after the removed one is returned. + */ iterator erase(iterator q) { size_type size = this->size() @@ -497,6 +824,20 @@ public: eina_array_pop(this->_impl._array); return q; } + + /** + * @brief Remove the elements between the given range. + * @param i Iterator pointing to the starting position to be removed. + * @param j Iterator pointing to the ending position to be removed. + * The element pointed by this iterator is not removed. + * @return Iterator pointing to the new position of the first + * non-removed element after the removed ones (i.e. the one + * originally pointed by @p j). + * + * This member function removes the elements between the iterators + * @p i and @p j, including the element pointed by @p i but not the + * element pointed by @j. + */ iterator erase(iterator i, iterator j) { size_type size = this->size() @@ -508,6 +849,19 @@ public: eina_array_pop(this->_impl._array); return i; } + + /** + * @brief Replace the content of the array by the elements in the given range. + * @param i Iterator pointing to the beginning of the elements to be copied. + * @param j Iterator pointing to the end of the elements to be copied. + * Note that the element pointed by j will NOT be copied. + * + * This member function replaces the current elements by copies of the + * elements between the iterators @p i and @p j, including the element + * pointed by @p i but not the one pointed by @p j. The size of the + * array is adjusted accordingly and the newly copied elements remain + * in their original order. + */ template void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -515,123 +869,378 @@ public: clear(); insert(end(), i, j); } + + /** + * @brief Replace the content of the array by @p n copies @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + */ void assign(size_type n, value_type const& t) { clear(); insert(end(), n, t); } + + /** + * @brief Get a reference to the last element. + * @return Reference to the last element in the array. + */ value_type& back() { return _ptr_array_access_traits::back(this->_impl._array); } + + /** + * @brief Get a constant reference to the last element. + * @return Constant reference to the last element in the array. + * + * Version of @ref back() for const-qualified objects. Returns a + * constant reference instead. + */ value_type const& back() const { return _ptr_array_access_traits::back(this->_impl._array); } + + /** + * @brief Get a reference to the first element. + * @return Reference to the first element of the array. + */ value_type& front() { return _ptr_array_access_traits::front(this->_impl._array); } + + /** + * @brief Get a constant reference to the first element. + * @return Constant reference to the first element of the array. + * + * Version of @ref front() for const-qualified objects. Returns a + * constant reference instead. + */ value_type const& front() const { return _ptr_array_access_traits::front(this->_impl._array); } + + /** + * @brief Get a constant reference to the element at the given position. + * @param index Position of the element in the array. + * @return Constant reference to element at position @p index. + * + * Version of @ref operator[](size_type index) for const-qualified + * objects. Returns a constant reference instead. + */ const_reference operator[](size_type index) const { return _ptr_array_access_traits::index(this->_impl._array, index); } + + /** + * @brief Get a reference to the element at the given position. + * @param index Position of the element in the array. + * @return Reference to element at position @p index. + */ reference operator[](size_type index) { return _ptr_array_access_traits::index(this->_impl._array, index); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * Version of @ref begin() for const-qualified objects. Returns a + * constant iterator instead. + */ const_iterator begin() const { return _ptr_array_access_traits::begin(this->_impl._array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * Version of @ref end() for const-qualified objects. Returns a + * constant iterator instead. + */ const_iterator end() const { return _ptr_array_access_traits::end(this->_impl._array); } + + /** + * @brief Get an iterator pointing to the first element of the array. + * @return Iterator to the initial position of the array. + * + * This member function returns an iterator pointing to the first + * element of the array. If the array is empty the returned iterator + * is the same as the one returned by @ref end(). + */ iterator begin() { return _ptr_array_access_traits::begin(this->_impl._array); } + + /** + * @brief Get an iterator to the position following the last element of the array. + * @return Iterator to the final position of the array. + * + * This member function returns an iterator to the position following + * the last element in the array. If the array is empty the returned + * iterator is the same as the one returned by @ref begin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ iterator end() { return _ptr_array_access_traits::end(this->_impl._array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * Version of @ref rbegin() for const-qualified objects. Returns a + * constant reverse iterator instead. + */ const_reverse_iterator rbegin() const { return _ptr_array_access_traits::rbegin(this->_impl._array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * Version of @ref rend() for const-qualified objects. Returns a + * constant reverse iterator instead. + */ const_reverse_iterator rend() const { return _ptr_array_access_traits::rend(this->_impl._array); } + + /** + * @brief Get a reverse iterator pointing to the reverse begin of the array. + * @return Reverse iterator pointing to the reverse begin of the array. + * + * This member function returns a reverse iterator pointing to the + * last element of the array. If the array is empty the returned + * reverse iterator is the same as the one returned by @ref rend(). + */ reverse_iterator rbegin() { return _ptr_array_access_traits::rbegin(this->_impl._array); } + + /** + * @brief Get a reverse iterator pointing to the reverse end of the array. + * @return Reverse iterator pointing to the reverse end of the array. + * + * This member function returns a reverse iterator pointing to the + * position before the first element of the array. If the array is + * empty the returned iterator is the same as the one returned by + * @ref rbegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ reverse_iterator rend() { return _ptr_array_access_traits::rend(this->_impl._array); } + + /** + * @brief Get a constant iterator pointing to the first element of the array. + * @return Constant iterator to the initial position of the array. + * + * This member function works like @ref begin() const but is granted + * to return a constant iterator even for arrays that are not + * const-qualified. + */ const_iterator cbegin() const { return _ptr_array_access_traits::cbegin(this->_impl._array); } + + /** + * @brief Get a constant iterator to the position following the last element of the array. + * @return Constant iterator to the final position of the array. + * + * This member function works like @ref end() const but is granted to + * return a constant iterator even for arrays that are not + * const-qualified. + */ const_iterator cend() const { return _ptr_array_access_traits::cend(this->_impl._array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the array. + * @return Constant reverse iterator pointing to the reverse begin of the array. + * + * This member function works like @ref rbegin() const but is granted + * to return a constant reverse iterator even for arrays that are not + * const-qualified. + */ const_reverse_iterator crbegin() const { return _ptr_array_access_traits::crbegin(this->_impl._array); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the array. + * @return Constant reverse iterator pointing to the reverse end of the array. + * + * This member function works like @ref rend() const but is granted to + * return a constant reverse iterator even for arrays that are not + * const-qualified. + */ const_reverse_iterator crend() const { return _ptr_array_access_traits::crend(this->_impl._array); } + + /** + * @brief Get an eina::iterator pointing to the first element of the array. + * @return eina::iterator to the initial position of the array. + * + * This member function returns an eina::iterator pointing to + * the first element of the array. If the array is empty the returned + * iterator is the same as the one returned by @ref iend(). + */ eina::iterator ibegin() { return _ptr_array_access_traits::ibegin(this->_impl._array); } + + /** + * @brief Get an eina::iterator to the position following the last element of the array. + * @return eina::iterator to the final position of the array. + * + * This member function returns an eina::iterator to the + * position following the last element in the array. If the array is + * empty the returned iterator is the same as the one returned by + * @ref ibegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ eina::iterator iend() { return _ptr_array_access_traits::iend(this->_impl._array); } + + /** + * @brief Get a constant eina::iterator pointing to the first element of the array. + * @return Constant eina::iterator to the initial position of the array. + * + * Version of @ref ibegin() for const-qualified objects. Returns a + * constant eina::iterator instead. + */ eina::iterator ibegin() const { return _ptr_array_access_traits::ibegin(this->_impl._array); } + + /** + * @brief Get an constant eina::iterator to the position following the last element of the array. + * @return Constant eina::iterator to the final position of the array. + * + * Version of @ref iend() for const-qualified objects. Returns a + * constant eina::iterator instead. + */ eina::iterator iend() const { return _ptr_array_access_traits::iend(this->_impl._array); } + + /** + * @brief Get an eina::iterator pointing to the first element of the array. + * @return eina::iterator to the initial position of the array. + * + * This member function works like @ref ibegin() const but is granted + * to return a constant iterator even for arrays that are not + * const-qualified. + */ eina::iterator cibegin() const { return _ptr_array_access_traits::cibegin(this->_impl._array); } + + /** + * @brief Get an constant eina::iterator to the position following the last element of the array. + * @return Constant eina::iterator to the final position of the array. + * + * This member function works like @ref iend() const but is granted to + * return a constant iterator even for arrays that are not + * const-qualified. + */ eina::iterator ciend() const { return _ptr_array_access_traits::ciend(this->_impl._array); } + + /** + * @brief Swap content between two arrays. + * @param other Other @c ptr_array of the same type. + */ void swap(ptr_array& other) { std::swap(this->_impl._array, other._impl._array); } + + /** + * @brief Get the maximum number of elements @c ptr_array can hold. + * @return Maximum number of elements a @c ptr_array can hold. + */ size_type max_size() const { return -1; } + /** + * @brief Get a handle for the wrapped Eina_Array. + * @return Handle for the native Eina array. + * + * This member function returns the native Eina_Array handle that is + * wrapped inside this object. + * + * @warning It is important to take care when using it, since the + * handle will be automatically release upon object destruction. + */ Eina_Array* native_handle() { return this->_impl._array; } + + /** + * @brief Get a constant handle for the wrapped Eina_Array. + * @return Constant handle for the native Eina array. + * + * Version of @ref native_handle() for const-qualified objects. + * Returns a constant handle instead. + * + * @see native_handle() + */ Eina_Array const* native_handle() const { return this->_impl._array; } }; +/** + * @brief Check if both arrays are equal. + * @param lhs @c ptr_array at the left side of the expression. + * @param rhs @c ptr_array at the right side of the expression. + * @return @c true if the arrays are equals, @c false otherwise. + * + * This operator checks if the given arrays are equal. To be considered + * equal both arrays need to have the same number of elements, and each + * element in one array must be equal to the element at the same + * position in the other array. + */ template bool operator==(ptr_array const& lhs, ptr_array const& rhs) { @@ -639,18 +1248,39 @@ bool operator==(ptr_array const& lhs, ptr_array const& lhs, ptr_array const& rhs). + */ template bool operator!=(ptr_array const& lhs, ptr_array const& rhs) { return !(lhs == rhs); } +/** + * @brief Swap content between two arrays. + * @param other Other @c ptr_array of the same type. + */ template void swap(ptr_array& lhs, ptr_array& rhs) { lhs.swap(rhs); } +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_ptrlist.hh b/src/bindings/eina_cxx/eina_ptrlist.hh index e918dfda02..f723f61180 100644 --- a/src/bindings/eina_cxx/eina_ptrlist.hh +++ b/src/bindings/eina_cxx/eina_ptrlist.hh @@ -10,8 +10,24 @@ #include #include +/** + * @addtogroup Eina_Cxx_Containers_Group + * + * @{ + */ + namespace efl { namespace eina { +/** + * @defgroup Eina_Cxx_Pointer_List_Group List of Pointers + * @ingroup Eina_Cxx_Containers_Group + * + * @{ + */ + +/** + * @internal + */ struct _ptr_list_iterator_base { typedef std::ptrdiff_t difference_type; @@ -26,6 +42,9 @@ protected: Eina_List *_list, *_node; }; +/** + * @internal + */ template struct _ptr_list_iterator : _ptr_list_iterator_base { @@ -95,6 +114,9 @@ struct _ptr_list_iterator : _ptr_list_iterator_base } }; +/** + * @internal + */ struct _ptr_list_access_traits { template @@ -242,6 +264,9 @@ static bool empty(Eina_List const* list) }; +/** + * @internal + */ template struct _const_range_ptr_list { @@ -320,12 +345,18 @@ struct _const_range_ptr_list native_handle_type _list; }; +/** + * @internal + */ template void swap(_const_range_ptr_list& lhs, _const_range_ptr_list& rhs) { lhs.swap(rhs); } +/** + * @internal + */ template struct _mutable_range_ptr_list : _const_range_ptr_list { @@ -350,7 +381,7 @@ struct _mutable_range_ptr_list : _const_range_ptr_list native_handle_type native_handle() const { - return const_cast(_base_type::native_handle()); + return const_cast(_base_type::native_handle()); } value_type& back() const { @@ -381,52 +412,105 @@ struct _mutable_range_ptr_list : _const_range_ptr_list template class ptr_list; +/** + * @ingroup Eina_Cxx_Range_Group + * + * Range class for @ref ptr_list. + */ template struct range_ptr_list : _range_template { - typedef _range_template _base_type; - typedef typename _base_type::value_type value_type; - typedef typename _base_type::native_handle_type native_handle_type; + typedef _range_template _base_type; /**< Type for the base class. */ + typedef typename _base_type::value_type value_type; /**< The type of each element. */ + typedef typename _base_type::native_handle_type native_handle_type; /** Type for the native Eina list handle. */ + /** + * @brief Creates a range from a native Eina list handle. + */ range_ptr_list(native_handle_type list) : _base_type(list) {} + + /** + * @brief Creates a range from a @c ptr_list object. + */ template range_ptr_list(ptr_list& list) : _base_type(list.native_handle()) {} }; +/** + * Common implementations for @c ptr_list. + */ template struct _ptr_list_common_base { - typedef CloneAllocator clone_allocator_type; + typedef CloneAllocator clone_allocator_type; /**< Type for the clone allocator. */ + /** + * @brief Creates an list with the given clone allocator. + */ _ptr_list_common_base(CloneAllocator clone_allocator) : _impl(clone_allocator) {} + + /** + * @brief Create a new object from a handle to a native Eina_List. + * @param _list Handle to a native Eina_List. + * + * This constructor wraps a pre-allocated Eina_List providing an OOP + * interface to it. + * + * @warning It is important to note that the created object gains + * ownership of the handle, deallocating it at destruction time. + */ _ptr_list_common_base(Eina_List* _list) : _impl(_list) {} + + /** + * @brief Default constructor. Create an empty list. + * + * This constructor creates a list with no elements. + */ _ptr_list_common_base() {} + /** + * @internal + */ CloneAllocator& _get_clone_allocator() { return _impl; } + + /** + * @internal + */ CloneAllocator const& _get_clone_allocator() const { return _impl; } + + /** + * @internal + */ void _delete_clone(T const* p) { _get_clone_allocator().deallocate_clone(p); } + + /** + * @internal + */ T* _new_clone(T const& a) { return _get_clone_allocator().allocate_clone(a); } + /** + * @internal + */ struct _ptr_list_impl : CloneAllocator { _ptr_list_impl() : _list(0) {} @@ -434,40 +518,79 @@ struct _ptr_list_common_base : clone_allocator_type(allocator), _list(0) {} Eina_List* _list; - }; + }; + /** + * @internal + */ _ptr_list_impl _impl; private: + /** Disabled copy constructor. */ _ptr_list_common_base(_ptr_list_common_base const& other); + /** Disabled assignment operator. */ _ptr_list_common_base& operator=(_ptr_list_common_base const& other); }; +/** + * List class. It provides an OOP interface to the @c Eina_List + * functions, and automatically take care of allocating and deallocating + * resources using the RAII programming idiom. + * + * It also provides additional member functions to facilitate the access + * to the list content, much like a STL list. + */ template class ptr_list : protected _ptr_list_common_base { - typedef _ptr_list_common_base _base_type; + typedef _ptr_list_common_base _base_type; /**< Type for the base class. */ public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef _ptr_list_iterator const_iterator; - typedef _ptr_list_iterator iterator; - typedef T* pointer; - typedef T const* const_pointer; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef CloneAllocator clone_allocator_type; + typedef T value_type; /**< The type of each element. */ + typedef T& reference; /**< Type for a reference to an element. */ + typedef T const& const_reference; /**< Type for a constant reference to an element. */ + typedef _ptr_list_iterator const_iterator; /**< Type for a iterator for this container. */ + typedef _ptr_list_iterator iterator; /**< Type for a constant iterator for this container. */ + typedef T* pointer; /**< Type for a pointer to an element. */ + typedef T const* const_pointer; /**< Type for a constant pointer for an element. */ + typedef std::size_t size_type; /**< Type for size information. */ + typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */ + typedef CloneAllocator clone_allocator_type; /** Type for the clone allocator. */ - typedef std::reverse_iterator reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ + typedef std::reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ + /** + * @brief Default constructor. Create an empty list. + * + * This constructor creates a @c ptr_list object with no elements. + */ ptr_list() {} + + /** + * @brief Construct an list object with @p n copies of @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + * + * This constructor creates an @c ptr_list with @p n elements, each + * one as a copy of @p t. + */ ptr_list(size_type n, const_reference t) { while(n--) push_back(t); } + + /** + * @brief Create a list with elements from the given range. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @param alloc Clone allocator to be used. + * + * This constructor creates a @c ptr_list with copies of the elements + * between @p i and @p j in the same order. + * + * @note The ending element (pointed by @p j) is not copied. + */ template ptr_list(InputIterator i, InputIterator const& j , clone_allocator_type const& alloc = clone_allocator_type() @@ -480,28 +603,61 @@ public: ++i; } } + + /** + * @brief Copy constructor. Creates a copy of the given @c ptr_list. + * @param other Another @c ptr_list of the same type. + * + * This constructor creates a @c ptr_list containing a copy of each + * element inside @p other in the same order. + */ ptr_list(ptr_list const& other) : _base_type() { insert(end(), other.begin(), other.end()); } + + /** + * @brief Creates a copy of a @c ptr_list with a different clone allocator. + * @param other Another @c ptr_list with a different clone allocator. + * + * This constructor creates a @c ptr_list containing a copy of each + * element inside @p other in the same order, even if the given list + * uses a different clone allocator. + */ template ptr_list(ptr_listconst& other) : _base_type() { insert(end(), other.begin(), other.end()); } + + /** + * @brief Destructor. Release all allocated elements. + */ ~ptr_list() { clear(); } + + /** + * @brief Replace the current content with the cotent of another list. + * @param other Another @c ptr_list of the same type. + * + * This assignment operator replaces the content of the list by a copy + * of the content of @p other. The list size is adjusted accordingly + * and the newly copied elements keep their original order. + */ ptr_list& operator=(ptr_listconst& other) { clear(); insert(end(), other.begin(), other.end()); return *this; } - + + /** + * @brief Remove all the elements of the list. + */ void clear() { for(iterator first = begin(), last = end(); first != last; ++first) @@ -509,27 +665,80 @@ public: eina_list_free(this->_impl._list); this->_impl._list = 0; } + + /** + * @brief Get the current size of the list. + * @return Number of elements in the list. + * + * This member function returns the current number of elements inside + * the list. + */ std::size_t size() const { return _ptr_list_access_traits::size(this->_impl._list); } + + /** + * @brief Check if the list is empty. + * @return @c true if the list is empty, @c false otherwise. + * + * This member function returns @c true if the list does not contain + * any elements, otherwise it returns @c false. + */ bool empty() const { return _ptr_list_access_traits::empty(this->_impl._list); } + + /** + * @brief Get the clone allocator of the list. + * @return Reference to the clone allocator. + */ clone_allocator_type get_clone_allocator() const { return clone_allocator_type(this->_get_clone_allocator()); } + + /** + * @brief Add a copy of the given element at the end of the list. + * @param a Element to be added at the end of the list. + * + * This member function allocates a new element, as a copy of @p a, + * and inserts it at the end of the list. + */ void push_back(const_reference a) { push_back(this->_new_clone(a)); } + + /** + * @brief Add the object pointed by @p p as a element at the end of the list. + * @param p Pointer to a pre-allocated element to be inserted at the end of the list. + * + * This member function adds the object pointed by @p p as a element + * at the end of the list. The list gains ownership of the pointer and + * nothing is copied. + * + * @warning The list gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ void push_back(pointer p) { std::unique_ptr p1(p); push_back(p1); } + + /** + * @brief Add the object pointed by @p p as a element at the end of the list. + * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the end of the list. + * + * This member function adds the object pointed by the given + * @c unique_ptr as a element at the end of the list. The object + * ownership is transfered to the list and nothing is copied. + * + * @warning The list gains ownership of the object managed by the + * given @c unique_ptr and will release it upon element destruction. + */ void push_back(std::unique_ptr& p) { Eina_List* new_list = eina_list_append(this->_impl._list, p.get()); @@ -541,15 +750,47 @@ public: else throw std::bad_alloc(); } + + /** + * @brief Add a copy of the given element at the beginning of the list. + * @param a Element to be added at the beginning of the list. + * + * This member function allocates a new element, as a copy of @p a, + * and inserts it at the beginning of the list. + */ void push_front(const_reference a) { push_front(this->new_clone(a)); } + + /** + * @brief Add the object pointed by @p p as a element at the beginning of the list. + * @param p Pointer to a pre-allocated element to be inserted at the beginning of the list. + * + * This member function adds the object pointed by @p p as a element + * at the beginning of the list. The list gains ownership of the + * pointer and nothing is copied. + * + * @warning The list gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ void push_front(pointer p) { std::unique_ptr p1(p); push_front(p1); } + + /** + * @brief Add the object pointed by @p p as a element at the beginning of the list. + * @param p Reference to a @c unique_ptr pointing to a element to be inserted at the beginning of the list. + * + * This member function adds the object pointed by the given + * @c unique_ptr as a element at the beginning of the list. The object + * ownership is transfered to the list and nothing is copied. + * + * @warning The list gains ownership of the object managed by the + * given @c unique_ptr and will release it upon element destruction. + */ void push_front(std::unique_ptr& p) { Eina_List* new_list = eina_list_prepend(this->_impl._list, p.get()); @@ -561,23 +802,81 @@ public: else throw std::bad_alloc(); } + + /** + * @brief Remove the last element of the list. + */ void pop_back() { this->_impl._list = eina_list_remove_list(this->_impl._list, eina_list_last(this->_impl._list)); } + + /** + * @brief Remove the first element of the list. + */ void pop_front() { this->_impl._list = eina_list_remove_list(this->_impl._list, this->_impl._list); } + + /** + * @brief Insert a copy of the given element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param t Value to be copied to the new element. + * @return Iterator pointing to the new element inserted. + * + * This member function inserts a copy of the element @p t at the + * position @p i. The new element comes right before the element + * originally pointed by @p i. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + */ iterator insert(iterator i, value_type const& t) { return insert(i, this->_new_clone(t)); - } + } + + /** + * @brief Insert the object pointed by @p pv as a element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param pv Pointer to a pre-allocated object to be inserted to the list. + * @return Iterator pointing to the new element inserted. + * + * This member function adds the object pointed by @p pv as a element + * at the given position. The new element comes right before the + * element originally pointed by @p i. The list gains ownership of + * the pointer and nothing is copied. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + * + * @warning The list gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ iterator insert(iterator i, pointer pv) { std::unique_ptr p(pv); return insert(i, p); } + + /** + * @brief Insert the object pointed by @p p as a element at the given position. + * @param i Iterator pointing to the position where the new element will be inserted. + * @param p Reference to a @c unique_ptr pointing to the element to be inserted in the list. + * @return Iterator pointing to the new element inserted. + * + * This member function adds the object pointed by @p p as a element + * at the given position. The new element comes right before the + * element originally pointed by @p i. The object ownership is + * transfered to the list and nothing is copied. + * + * At the end, a valid iterator pointing to the element just inserted + * is returned. + * + * @warning The list gains ownership of the object managed by the + * given @c unique_ptr and will release it upon element destruction. + */ iterator insert(iterator i, std::unique_ptr& p) { this->_impl._list = _eina_list_prepend_relative_list @@ -591,7 +890,22 @@ public: ? ::eina_list_prev(i.native_handle()) : ::eina_list_last(this->_impl._list) ); - } + } + + /** + * @brief Insert @p n copies of @p t at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param t Value to be copied to each new inserted element. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts @p n new elements at position @p i + * in the list, each one as a copy of @p t. The new elements come + * right before the element originally pointed by @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ iterator insert(iterator i, size_t n, value_type const& t) { iterator r = i; @@ -601,6 +915,25 @@ public: insert(i, t); return r; } + + /** + * @brief Insert the object pointed by @p p and n-1 copies of it as elements at the given position. + * @param i Iterator pointing to the position where the new elements will be inserted. + * @param n Number of elements to be inserted. + * @param p Pointer to a pre-allocated object to be inserted in the list. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts the object pointed by @p p and + * n-1 copies of it as elements at the given position. The + * new elements come right before the element originally pointed by + * @p i. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + * + * @warning The list gains ownership of the given pointer and will + * release the pointed object upon element destruction. + */ iterator insert(iterator i, size_t n, pointer p) { iterator r = i; @@ -610,6 +943,22 @@ public: insert(i, this->_new_clone(p)); return r; } + + /** + * @brief Insert the elements between the given range at the given position. + * @param p Iterator pointing to the position where the new elements will be inserted. + * @param i Iterator to the initial position. The element pointed by this iterator will be copied. + * @param j Iterator to the final position. The element pointed by this iterator will NOT be copied. + * @return Iterator pointing to the first inserted element. + * + * This member function inserts a copy of the elements between @p i + * and @p j at the position @p p. The new elements come right before + * the element originally pointed by @p p. Note that the element + * pointed by @p j is not copied. + * + * At the end, a valid iterator pointing to the first element inserted + * is returned. + */ template iterator insert(iterator p, InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -627,6 +976,16 @@ 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()) @@ -638,6 +997,20 @@ public: else return q; } + + /** + * @brief Remove the elements between the given range. + * @param i Iterator pointing to the starting position to be removed. + * @param j Iterator pointing to the ending position to be removed. + * The element pointed by this iterator is not removed. + * @return Iterator pointing to the new position of the first + * non-removed element after the removed ones (i.e. the one + * originally pointed by @p j). + * + * This member function removes the elements between the iterators + * @p i and @p j, including the element pointed by @p i but not the + * element pointed by @j. + */ iterator erase(iterator i, iterator j) { while(i != j) @@ -647,6 +1020,19 @@ public: else return end(); } + + /** + * @brief Replace the content of the list by the elements in the given range. + * @param i Iterator pointing to the beginning of the elements to be copied. + * @param j Iterator pointing to the end of the elements to be copied. + * Note that the element pointed by j will NOT be copied. + * + * This member function replaces the current elements by copies of the + * elements between the iterators @p i and @p j, including the element + * pointed by @p i but not the one pointed by @p j. The size of the + * list is adjusted accordingly and the newly copied elements remain + * in their original order. + */ template void assign(InputIterator i, InputIterator j , typename eina::enable_if::value>::type* = 0) @@ -654,123 +1040,376 @@ public: clear(); insert(end(), i, j); } + + /** + * @brief Replace the content of the list by @p n copies @p t. + * @param n Number of elements. + * @param t Value to be copied to each element. + */ void assign(size_type n, value_type const& t) { clear(); insert(end(), n, t); } + + /** + * @brief Get a reference to the last element. + * @return Reference to the last element in the list. + */ value_type& back() { return _ptr_list_access_traits::back(this->_impl._list); } + + /** + * @brief Get a constant reference to the last element. + * @return Constant reference to the last element in the list. + * + * Version of @ref back() for const-qualified objects. Returns a + * constant reference instead. + */ value_type const& back() const { return _ptr_list_access_traits::back(this->_impl._list); } + + /** + * @brief Get a reference to the first element. + * @return Reference to the first element of the list. + */ value_type& front() { return _ptr_list_access_traits::front(this->_impl._list); } + + /** + * @brief Get a constant reference to the first element. + * @return Constant reference to the first element of the list. + * + * Version of @ref front() for const-qualified objects. Returns a + * constant reference instead. + */ value_type const& front() const { return _ptr_list_access_traits::front(this->_impl._list); } + + /** + * @brief Get a constant iterator pointing to the first element of the list. + * @return Constant iterator to the initial position of the list. + * + * Version of @ref begin() for const-qualified objects. Returns a + * constant iterator instead. + */ const_iterator begin() const { return _ptr_list_access_traits::cbegin(this->_impl._list); } + + /** + * @brief Get a constant iterator to the position following the last element of the list. + * @return Constant iterator to the final position of the list. + * + * Version of @ref end() for const-qualified objects. Returns a + * constant iterator instead. + */ const_iterator end() const { return _ptr_list_access_traits::cend(this->_impl._list); } + + /** + * @brief Get an iterator pointing to the first element of the list. + * @return Iterator to the initial position of the list. + * + * This member function returns an iterator pointing to the first + * element of the list. If the list is empty the returned iterator + * is the same as the one returned by @ref end(). + */ iterator begin() { return _ptr_list_access_traits::begin(this->_impl._list); } + + /** + * @brief Get an iterator to the position following the last element of the list. + * @return Iterator to the final position of the list. + * + * This member function returns an iterator to the position following + * the last element in the list. If the list is empty the returned + * iterator is the same as the one returned by @ref begin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ iterator end() { return _ptr_list_access_traits::end(this->_impl._list); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the list. + * @return Constant reverse iterator pointing to the reverse begin of the list. + * + * Version of @ref rbegin() for const-qualified objects. Returns a + * constant reverse iterator instead. + */ const_reverse_iterator rbegin() const { return _ptr_list_access_traits::rbegin(this->_impl._list); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the list. + * @return Constant reverse iterator pointing to the reverse end of the list. + * + * Version of @ref rend() for const-qualified objects. Returns a + * constant reverse iterator instead. + */ const_reverse_iterator rend() const { return _ptr_list_access_traits::rend(this->_impl._list); } + + /** + * @brief Get a reverse iterator pointing to the reverse begin of the list. + * @return Reverse iterator pointing to the reverse begin of the list. + * + * This member function returns a reverse iterator pointing to the + * last element of the list. If the list is empty the returned + * reverse iterator is the same as the one returned by @ref rend(). + */ reverse_iterator rbegin() { return _ptr_list_access_traits::rbegin(this->_impl._list); } + + /** + * @brief Get a reverse iterator pointing to the reverse end of the list. + * @return Reverse iterator pointing to the reverse end of the list. + * + * This member function returns a reverse iterator pointing to the + * position before the first element of the list. If the list is + * empty the returned iterator is the same as the one returned by + * @ref rbegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ reverse_iterator rend() { return _ptr_list_access_traits::rend(this->_impl._list); } + + /** + * @brief Get a constant iterator pointing to the first element of the list. + * @return Constant iterator to the initial position of the list. + * + * This member function works like @ref begin() const but is granted + * to return a constant iterator even for lists that are not + * const-qualified. + */ const_iterator cbegin() const { return _ptr_list_access_traits::cbegin(this->_impl._list); } + + /** + * @brief Get a constant iterator to the position following the last element of the list. + * @return Constant iterator to the final position of the list. + * + * This member function works like @ref end() const but is granted to + * return a constant iterator even for lists that are not + * const-qualified. + */ const_iterator cend() const { return _ptr_list_access_traits::cend(this->_impl._list); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse begin of the list. + * @return Constant reverse iterator pointing to the reverse begin of the list. + * + * This member function works like @ref rbegin() const but is granted + * to return a constant reverse iterator even for lists that are not + * const-qualified. + */ const_reverse_iterator crbegin() const { return _ptr_list_access_traits::crbegin(this->_impl._list); } + + /** + * @brief Get a constant reverse iterator pointing to the reverse end of the list. + * @return Constant reverse iterator pointing to the reverse end of the list. + * + * This member function works like @ref rend() const but is granted to + * return a constant reverse iterator even for lists that are not + * const-qualified. + */ const_reverse_iterator crend() const { return _ptr_list_access_traits::crend(this->_impl._list); } + + /** + * @brief Get an eina::iterator pointing to the first element of the list. + * @return eina::iterator to the initial position of the list. + * + * This member function returns an eina::iterator pointing to + * the first element of the list. If the list is empty the returned + * iterator is the same as the one returned by @ref iend(). + */ eina::iterator ibegin() { return _ptr_list_access_traits::ibegin(this->_impl._list); } + + /** + * @brief Get an eina::iterator to the position following the last element of the list. + * @return eina::iterator to the final position of the list. + * + * This member function returns an eina::iterator to the + * position following the last element in the list. If the list is + * empty the returned iterator is the same as the one returned by + * @ref ibegin(). + * + * @note Note that attempting to access this position causes undefined + * behavior. + */ eina::iterator iend() { return _ptr_list_access_traits::iend(this->_impl._list); } + + /** + * @brief Get a constant eina::iterator pointing to the first element of the list. + * @return Constant eina::iterator to the initial position of the list. + * + * Version of @ref ibegin() for const-qualified objects. Returns a + * constant eina::iterator instead. + */ eina::iterator ibegin() const { return _ptr_list_access_traits::ibegin(this->_impl._list); } + + /** + * @brief Get an constant eina::iterator to the position following the last element of the list. + * @return Constant eina::iterator to the final position of the list. + * + * Version of @ref iend() for const-qualified objects. Returns a + * constant eina::iterator instead. + */ eina::iterator iend() const { return _ptr_list_access_traits::iend(this->_impl._list); } + + /** + * @brief Get an eina::iterator pointing to the first element of the list. + * @return eina::iterator to the initial position of the list. + * + * This member function works like @ref ibegin() const but is granted + * to return a constant iterator even for lists that are not + * const-qualified. + */ eina::iterator cibegin() const { return _ptr_list_access_traits::cibegin(this->_impl._list); } + + /** + * @brief Get an constant eina::iterator to the position following the last element of the list. + * @return Constant eina::iterator to the final position of the list. + * + * This member function works like @ref iend() const but is granted to + * return a constant iterator even for lists that are not + * const-qualified. + */ eina::iterator ciend() const { return _ptr_list_access_traits::ciend(this->_impl._list); } + + /** + * @brief Swap content between two lists. + * @param other Other @c ptr_list of the same type. + */ void swap(ptr_list& other) { std::swap(this->_impl._list, other._impl._list); } + + /** + * @brief Get the maximum number of elements @c ptr_list can hold. + * @return Maximum number of elements a @c ptr_list can hold. + */ size_type max_size() const { return -1; } + /** + * @brief Get a handle for the wrapped @c Eina_List. + * @return Handle for the native Eina list. + * + * This member function returns the native Eina_List handle that is + * wrapped inside this object. + * + * @warning It is important to take care when using it, since the + * handle will be automatically released upon object destruction. + */ Eina_List* native_handle() { return this->_impl._list; } + + /** + * @brief Get a constant handle for the wrapped Eina_List. + * @return Constant handle for the native Eina list. + * + * Version of @ref native_handle() for const-qualified objects. + * Returns a constant handle instead. + * + * @see native_handle() + */ Eina_List const* native_handle() const { return this->_impl._list; } + + /** + * @brief Get a constant @ref eina::accessor for the list. + * @return Constant eina::accessor to the list. + * + * Version of @ref accessor() to const-qualified inline lists. Returns + * a const-qualified eina::accessor instead. + */ eina::accessor accessor() const { return eina::accessor(eina_list_accessor_new(this->_impl._list)); } + + /** + * @brief Get a @ref eina::accessor for the list. + * @return eina::accessor to the list. + */ eina::accessor accessor() { return eina::accessor(eina_list_accessor_new(this->_impl._list)); } }; +/** + * @brief Check if both lists are equal. + * @param lhs @c ptr_list at the left side of the expression. + * @param rhs @c ptr_list at the right side of the expression. + * @return @c true if the lists are equals, @c false otherwise. + * + * This operator checks if the given lists are equal. To be considered + * equal both lists need to have the same number of elements, and each + * element in one list must be equal to the element at the same + * position in the other list. + */ template bool operator==(ptr_list const& lhs, ptr_list const& rhs) { @@ -778,18 +1417,39 @@ bool operator==(ptr_list const& lhs, ptr_list const& lhs, ptr_list const& rhs). + */ template bool operator!=(ptr_list const& lhs, ptr_list const& rhs) { return !(lhs == rhs); } +/** + * @brief Swap content between two lists. + * @param other Other @c ptr_list of the same type. + */ template void swap(ptr_list& lhs, ptr_list& rhs) { lhs.swap(rhs); } +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_range_types.hh b/src/bindings/eina_cxx/eina_range_types.hh index cf8a4c80bf..8216adeb7f 100644 --- a/src/bindings/eina_cxx/eina_range_types.hh +++ b/src/bindings/eina_cxx/eina_range_types.hh @@ -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 struct _const_range_template { - typedef typename Traits::template const_iterator::type const_iterator; - typedef typename Traits::template iterator::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 reverse_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; + typedef typename Traits::template const_iterator::type const_iterator; /**< Type for constant iterator to the range. */ + typedef typename Traits::template iterator::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 reverse_iterator; /**< Type for reverse iterator to the range. */ + typedef std::reverse_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::type native_handle_type; - typedef _const_range_template _self_type; + typedef typename Traits::template const_native_handle::type native_handle_type; /**< Type for the native handle of the container. */ + typedef _const_range_template _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(_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(_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(_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(_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(_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(_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(_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(_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 void swap(_const_range_template& lhs, _const_range_template& rhs) { lhs.swap(rhs); } +/** + * @brief Range implementation for mutable collections. + */ template struct _mutable_range_template : _const_range_template { - typedef T value_type; - typedef typename Traits::template iterator::type iterator; - typedef std::reverse_iterator reverse_iterator; - typedef typename Traits::template native_handle::type native_handle_type; - typedef _const_range_template _base_type; + typedef T value_type; /**< The type of each element. */ + typedef typename Traits::template iterator::type iterator; /**< Type for a iterator to the range. */ + typedef std::reverse_iterator reverse_iterator; /**< Type for constant reverse iterator to the range. */ + typedef typename Traits::template native_handle::type native_handle_type; /**< Type for the native handle of the container. */ + typedef _const_range_template _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(_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(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(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(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(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(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(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 struct _range_template : private std::conditional ::value , _const_range_template::type, Traits> , _mutable_range_template >::type { - typedef std::integral_constant::value> is_mutable; - typedef typename std::remove_const::type value_type; + typedef std::integral_constant::value> is_mutable; /**< Type that specifies if the elements can be modified. */ + typedef typename std::remove_const::type value_type; /**< The type of each element. */ typedef typename std::conditional - , _const_range_template >::type _base_type; - typedef typename _base_type::native_handle_type native_handle_type; + , _const_range_template >::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::type const_iterator; - typedef typename _base_type::const_reverse_iterator const_reverse_iterator; - typedef typename Traits::template iterator::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::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::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 diff --git a/src/bindings/eina_cxx/eina_ref.hh b/src/bindings/eina_cxx/eina_ref.hh index 887a21f769..8a3b4e86ac 100644 --- a/src/bindings/eina_cxx/eina_ref.hh +++ b/src/bindings/eina_cxx/eina_ref.hh @@ -3,24 +3,75 @@ #include +/** + * @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 T& unref(T& t) { return t; } - + template T& unref(reference_wrapper t) { return t.get(); } +/** + * @} + */ + +/** + * @} + */ + }} +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_stringshare.hh b/src/bindings/eina_cxx/eina_stringshare.hh index 930d2aa44b..233c6f309b 100644 --- a/src/bindings/eina_cxx/eina_stringshare.hh +++ b/src/bindings/eina_cxx/eina_stringshare.hh @@ -7,11 +7,58 @@ #include #include +/** + * @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 NULL-terminated string to be shared. + * + * This constructor creates an eina::stringshare 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 eina::stringshare that steal the ownership of the given shared string. + * @param str Shared string whose ownership should be stolen. + * + * This constructor creates an eina::stringshare 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 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 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 eina::stringshare associated with the same shared string. + * @param other Another eina::stringshare. + * + * 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 eina::stringshare. + * + * 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 NULL-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 std::out_of_range 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 std::out_of_range. + */ 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 eina::stringshare. + */ 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 + * stringshare::const_iterator as a contiguous iterator. + */ template <> struct is_contiguous_iterator : true_type {}; +/** + * @brief Check if two eina::stringshare objects represent the same string. + * @return @c true if the strings of the objects are equal, @c false otherwise. + * + * This operator checks if two eina::stringshare 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 eina::stringshare 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 eina::stringshare object with a c-like string. + * @return @c true if the content of the eina::stringshare + * 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 eina::stringshare object with a c-like string. + * @return @c true if the content of the eina::stringshare + * 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 eina::stringshare object with a c-like string. + * @return @c true if the content of the eina::stringshare + * 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 eina::stringshare object with a c-like string. + * @return @c true if the content of the eina::stringshare + * 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 diff --git a/src/bindings/eina_cxx/eina_thread.hh b/src/bindings/eina_cxx/eina_thread.hh index 84bd0e53e7..320f038e12 100644 --- a/src/bindings/eina_cxx/eina_thread.hh +++ b/src/bindings/eina_cxx/eina_thread.hh @@ -13,23 +13,72 @@ #include #include +/** + * @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 std::mutex. + */ 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 eina::system_error with the code + * eina::errc::resource_deadlock_would_occur 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 eina::system_error with the code + * eina::errc::resource_deadlock_would_occur 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 eina::system_error with the code + * eina::errc::resource_deadlock_would_occur 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 std::lock_guard. + */ using std::lock_guard; + +/** + * @brief Manages a mutex object. + * + * Inherited for the STL object std::unique_lock. 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 std::condition_variable. + */ 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 eina::system_error 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 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 eina::system_error 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 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 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 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()(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 std::basic_ostream object. + */ template friend std::basic_ostream& operator<<(std::basic_ostream& 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 function; }; +/** + * @internal + */ inline void* create_thread(void* data, Eina_Thread) { arguments* args = static_cast(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 std::thread. + */ 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 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 thread::id 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 thread::id 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 void sleep_until(std::chrono::time_pointconst& 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 void sleep_for(std::chrono::durationconst& rel_time); } +/** + * @} + */ + } } +/** + * @internal + * Specialization of standard @c hash class to specify that a + * thread_id object should be handled as a unsigned long + * @{ + */ namespace std { template struct hash; @@ -352,5 +777,12 @@ struct hash< ::efl::eina::thread_id> : hash {}; } +/** + * @} + */ + +/** + * @} + */ #endif diff --git a/src/bindings/eina_cxx/eina_type_traits.hh b/src/bindings/eina_cxx/eina_type_traits.hh index bd22457de3..796a165379 100644 --- a/src/bindings/eina_cxx/eina_type_traits.hh +++ b/src/bindings/eina_cxx/eina_type_traits.hh @@ -6,8 +6,20 @@ #include #include +/** + * @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 { }; +/** + * @} + */ + } } +/** + * @} + */ + #endif diff --git a/src/bindings/eina_cxx/eina_value.hh b/src/bindings/eina_cxx/eina_value.hh index 6226878121..ca99b55544 100644 --- a/src/bindings/eina_cxx/eina_value.hh +++ b/src/bindings/eina_cxx/eina_value.hh @@ -6,8 +6,27 @@ #include #include +/** + * @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 struct _eina_value_traits; @@ -17,6 +36,9 @@ struct _eina_value_traits_base; template struct _eina_value_traits_aux; +/** + * @internal + */ template 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 : _eina_value_traits_base @@ -61,11 +86,17 @@ struct _eina_value_traits_aux } }; +/** + * @internal + */ template struct _eina_value_traits : _eina_value_traits_aux { }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -76,6 +107,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -86,6 +120,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -96,6 +133,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -106,6 +146,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -116,6 +159,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -126,6 +172,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -136,6 +185,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -146,6 +198,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -156,6 +211,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -166,6 +224,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -186,6 +247,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template <> struct _eina_value_traits : _eina_value_traits_base @@ -209,6 +273,9 @@ struct _eina_value_traits } }; +/** + * @internal + */ template struct _eina_value_traits::value>::type> : _eina_value_traits_base @@ -237,8 +304,15 @@ class value; template T get(value const& v); +/** + * Store generic value + */ class value { + /** + * @brief Initialize the eina::value with the given argument. + * @param v Argument that the eina::value will store. + */ template void primitive_init(T v) { @@ -246,67 +320,138 @@ class value _eina_value_traits::set(_raw, v); } public: + + /** + * @brief Default constructor. Create an empty generic value storage. + */ value() : _raw(_eina_value_traits::create()) { } + + /** + * @brief Create an generic value storage holding the given argument. + * @param v Value to be stored. + */ template 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 unsigned char value. + * @param v unsigned char value to be stored. + */ value(unsigned char v) { primitive_init(v); } + + /** + * @brief Create an generic value storage holding a unsigned short value. + * @param v unsigned short value to be stored. + */ value(unsigned short v) { primitive_init(v); } + + /** + * @brief Create an generic value storage holding a unsigned int value. + * @param v unsigned int value to be stored. + */ value(unsigned int v) { primitive_init(v); } + + /** + * @brief Create an generic value storage holding a unsigned long value. + * @param v unsigned long 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 eina::value object. + */ value(value const& other) : _raw(_eina_value_traits::create()) { if(!eina_value_copy(const_cast(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 eina::value object. + */ value& operator=(value const& other) { eina_value_flush(_raw); @@ -315,17 +460,41 @@ public: return *this; } + /** + * @brief Swap stored values with the given eina::value object. + * @param other Another eina::value 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 eina::value. + * @param v eina::value object. + * @param T Type of the value stored. + * @return Copy of the value stored in @p v. + * @throw eina::system_error with error the code + * @c EINA_ERROR_VALUE_FAILED if @p T doesn't match the type of + * the value currently stored. Or eina::system_error + * 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 friend T get(value const& v) { @@ -340,17 +524,39 @@ private: } }; +/** + * @brief Swap the stored values between the given eina::value objects. + * @param lhs First eina::value object. + * @param rhs Second eina::value object. + */ inline void swap(value& lhs, value& rhs) { lhs.swap(rhs); } +/** + * @brief Compare if the stored values are equal. + * @param lhs eina::value object at the left side of the expression. + * @param rhs eina::value 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 eina::value objects. + * @param lhs eina::value object at the left side of the expression. + * @param rhs eina::value 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()(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 eina::value objects. + * @param lhs eina::value object at the left side of the expression. + * @param rhs eina::value 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()(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 eina::value objects. + * @param lhs eina::value object at the left side of the expression. + * @param rhs eina::value 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 eina::value objects. + * @param lhs eina::value object at the left side of the expression. + * @param rhs eina::value 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 eina::value object at the left side of the expression. + * @param rhs eina::value 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