diff --git a/src/Makefile_Eet_Cxx.am b/src/Makefile_Eet_Cxx.am index 2e1487da8e..b09223a2d5 100644 --- a/src/Makefile_Eet_Cxx.am +++ b/src/Makefile_Eet_Cxx.am @@ -27,7 +27,7 @@ tests_eet_cxx_eet_cxx_suite_CPPFLAGS = \ -DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eet_cxx\" \ -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eet_cxx\" \ -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eet_cxx\" \ -@CHECK_CFLAGS@ @EET_CXX_CFLAGS@ @EINA_CXX_CFLAGS@ @EET_CFLAGS@ @EINA_CFLAGS@ +@EO_CFLAGS@ @CHECK_CFLAGS@ @EET_CXX_CFLAGS@ @EINA_CXX_CFLAGS@ @EET_CFLAGS@ @EINA_CFLAGS@ tests_eet_cxx_eet_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EET_LIBS@ tests_eet_cxx_eet_cxx_suite_DEPENDENCIES = @USE_EET_INTERNAL_LIBS@ endif diff --git a/src/Makefile_Eina_Cxx.am b/src/Makefile_Eina_Cxx.am index cfac2478a6..0acb42052b 100644 --- a/src/Makefile_Eina_Cxx.am +++ b/src/Makefile_Eina_Cxx.am @@ -58,9 +58,11 @@ tests_eina_cxx_eina_cxx_suite_CXXFLAGS = -I$(top_builddir)/src/lib/efl \ -DPACKAGE_BUILD_DIR=\"$(abs_top_builddir)/src/tests/eina_cxx\" \ -DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eina_cxx\" \ @CHECK_CFLAGS@ \ +@EO_CFLAGS@ \ +@EO_CXX_CFLAGS@ \ @EINA_CXX_CFLAGS@ -tests_eina_cxx_eina_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EINA_LIBS@ -tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ +tests_eina_cxx_eina_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EINA_LIBS@ @USE_EO_LIBS@ +tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_INTERNAL_LIBS@ endif endif diff --git a/src/bindings/eina_cxx/eina_array.hh b/src/bindings/eina_cxx/eina_array.hh new file mode 100644 index 0000000000..eea64fcfeb --- /dev/null +++ b/src/bindings/eina_cxx/eina_array.hh @@ -0,0 +1,337 @@ +#ifndef EINA_ARRAY_HH_ +#define EINA_ARRAY_HH_ + +#include +#include +#include + +#include + +namespace efl { namespace eina { + +template +class array : ptr_array::value + , heap_no_copy_allocator, CloneAllocator>::type> +{ + typedef ptr_array::value + , heap_no_copy_allocator, CloneAllocator>::type> _base_type; +public: + typedef typename _base_type::value_type value_type; /**< The type of each element. */ + typedef typename _base_type::reference reference; /**< Type for a reference to an element. */ + typedef typename _base_type::const_reference const_reference; /**< Type for a constant reference to an element. */ + typedef typename _base_type::const_iterator const_iterator; /**< Type for a iterator for this container. */ + typedef typename _base_type::iterator iterator; /**< Type for a constant iterator for this container. */ + typedef typename _base_type::pointer pointer; /**< Type for a pointer to an element. */ + typedef typename _base_type::const_pointer const_pointer; /**< Type for a constant pointer for an element. */ + typedef typename _base_type::size_type size_type; /**< Type for size information used in the array. */ + typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */ + typedef typename _base_type::clone_allocator_type clone_allocator_type; /** Type for the clone allocator. */ + + typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator for this container. */ + typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for reverse iterator for this container. */ + + using _base_type::_base_type; + using _base_type::clear; + using _base_type::size; + using _base_type::empty; + using _base_type::get_clone_allocator; + using _base_type::push_back; + using _base_type::pop_back; + using _base_type::insert; + using _base_type::erase; + using _base_type::assign; + using _base_type::back; + using _base_type::front; + using _base_type::operator[]; + using _base_type::begin; + using _base_type::end; + using _base_type::rbegin; + using _base_type::rend; + using _base_type::cbegin; + using _base_type::cend; + using _base_type::crbegin; + using _base_type::crend; + using _base_type::ibegin; + using _base_type::iend; + using _base_type::cibegin; + using _base_type::ciend; + using _base_type::swap; + using _base_type::max_size; + using _base_type::native_handle; + + friend bool operator==(array const& lhs, array const& rhs) + { + return static_cast<_base_type const&>(lhs) == static_cast<_base_type const&>(rhs); + } +}; + +/** + * @internal + */ +template +struct _ptr_eo_array_iterator : _ptr_array_iterator +{ + typedef _ptr_array_iterator _base_type; + typedef _ptr_eo_array_iterator _self_type; + typedef typename remove_cv::type value_type; + typedef value_type* pointer; + typedef value_type& reference; + + _base_type& _base() { return *this; } + _base_type const& _base() const { return *this; } + + _ptr_eo_array_iterator(_base_type const& base) : _base_type(base) {} + _ptr_eo_array_iterator() {} + explicit _ptr_eo_array_iterator(void** ptr) + : _base_type(ptr) + { + } + _ptr_eo_array_iterator(_ptr_eo_array_iterator const& other) + : _base_type(static_cast<_base_type const&>(other)) + { + } + _self_type& operator=(_self_type const& other) + { + this->_base_type::operator=(other); + return *this; + } + _self_type& operator++() + { + ++_base(); + return *this; + } + _self_type operator++(int) + { + _self_type tmp(*this); + ++_base(); + return tmp; + } + _self_type& operator--() + { + --_base(); + return *this; + } + _self_type operator--(int) + { + _self_type tmp(*this); + --_base(); + return tmp; + } + reference operator*() const + { + return *static_cast(static_cast(native_handle())); + } + pointer operator->() const + { + return &**this; + } + + using _base_type::native_handle; +}; + +template +class array::value>::type> + : ptr_array::value + , eo_clone_allocator, CloneAllocator>::type> +{ + typedef ptr_array::value + , eo_clone_allocator, CloneAllocator>::type> _base_type; + typedef array _self_type; +public: + 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_eo_array_iterator const_iterator; /**< Type for a iterator for this container. */ + typedef _ptr_eo_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 typename _base_type::size_type size_type; /**< Type for size information used in the array. */ + typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */ + typedef typename _base_type::clone_allocator_type clone_allocator_type; /** Type for the clone allocator. */ + + 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. */ + + explicit array(Eina_Array* handle) + : _base_type(handle) {} + array(clone_allocator_type alloc) : _base_type(alloc) {} + array() {} + array(size_type n, const_reference t) + { + while(n--) + push_back(t); + } + template + array(InputIterator i, InputIterator const& j + , clone_allocator_type const& alloc = clone_allocator_type() + , typename eina::enable_if::value>::type* = 0) + : _base_type(alloc) + { + while(i != j) + { + push_back(*i); + ++i; + } + } + array(array const& other) + : _base_type() + { + insert(end(), other.begin(), other.end()); + } + template + array(arrayconst& other) + : _base_type() + { + insert(end(), other.begin(), other.end()); + } + array& operator=(arrayconst& other) + { + clear(); + insert(end(), other.begin(), other.end()); + return *this; + } + + using _base_type::clear; + using _base_type::size; + using _base_type::empty; + using _base_type::get_clone_allocator; + using _base_type::pop_back; + + void push_back(const_reference w) + { + _base_type::push_back(this->_new_clone(*w._eo_ptr())); + } + iterator insert(iterator i, value_type const& t) + { + return _base_type::insert(i, this->_new_clone(*t._eo_ptr())); + } + iterator insert(iterator i, size_t n, value_type const& t) + { + return _base_type::insert(i, n, this->_new_clone(*t._eo_ptr())); + } + template + iterator insert(iterator p, InputIterator i, InputIterator j + , typename eina::enable_if::value>::type* = 0) + { + size_type index = p.native_handle() - this->_impl._array->data; + while(i != j) + { + p = insert(p, *i); + ++p; + ++i; + } + return iterator(this->_impl._array->data + index); + } + iterator erase(iterator p) + { + return _base_type::erase(p); + } + iterator erase(iterator i, iterator j) + { + return _base_type::erase(i, j); + } + template + void assign(InputIterator i, InputIterator j + , typename eina::enable_if::value>::type* = 0) + { + clear(); + insert(end(), i, j); + } + + void assign(size_type n, value_type const& t) + { + clear(); + insert(end(), n, t); + } + reference front() + { + return *static_cast(static_cast(&native_handle()->data[0])); + } + reference back() + { + return *static_cast(static_cast(&native_handle()->data[eina_array_count(native_handle())-1])); + } + const_reference front() const { return const_cast<_self_type*>(this)->front(); } + const_reference back() const { return const_cast<_self_type*>(this)->back(); } + + const_reference operator[](size_type n) const + { + return *static_cast(static_cast(&native_handle()->data[n])); + } + reference operator[](size_type n) + { + return *static_cast(static_cast(&native_handle()->data[n])); + } + + iterator begin() + { + return iterator(&native_handle()->data[0]); + } + iterator end() + { + return iterator(&native_handle()->data[ ::eina_array_count(native_handle())]); + } + const_iterator begin() const + { + return const_cast< _self_type*>(this)->begin(); + } + const_iterator end() const + { + return const_cast< _self_type*>(this)->end(); + } + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rbegin() const + { + return reverse_iterator(end()); + } + const_reverse_iterator rend() const + { + return reverse_iterator(begin()); + } + const_iterator cbegin() const + { + return begin(); + } + const_iterator cend() const + { + return cend(); + } + const_reverse_iterator crbegin() const + { + return rbegin(); + } + const_reverse_iterator crend() const + { + return rend(); + } + + using _base_type::swap; + using _base_type::max_size; + using _base_type::native_handle; + + friend bool operator==(array const& lhs, array const& rhs) + { + return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } +}; + +template +bool operator!=(array const& lhs, array const& rhs) +{ + return !(lhs == rhs); +} + +} } + +#endif diff --git a/src/bindings/eina_cxx/eina_clone_allocators.hh b/src/bindings/eina_cxx/eina_clone_allocators.hh index 2e8ae4516b..824d6d6ce9 100644 --- a/src/bindings/eina_cxx/eina_clone_allocators.hh +++ b/src/bindings/eina_cxx/eina_clone_allocators.hh @@ -1,6 +1,8 @@ #ifndef EINA_CLONE_ALLOCATORS_HH_ #define EINA_CLONE_ALLOCATORS_HH_ +#include + #include #include #include @@ -25,6 +27,11 @@ namespace efl { namespace eina { * @{ */ +/* + * @internal + */ +struct default_clone_allocator_placeholder; + /** * This allocator creates copies of objects on the heap, calling their * copy constructor to make then equivalent to the given reference. @@ -50,6 +57,24 @@ struct heap_copy_allocator } }; +/** + * This allocator creates copies of Eo classes through eo_ref + * + * The created objects are released using eo_unref + */ +struct eo_clone_allocator +{ + static Eo* allocate_clone(Eo const& v) + { + return ::eo_ref(&v); + } + + static void deallocate_clone(Eo const* p) + { + ::eo_unref(const_cast(p)); + } +}; + /** * This allocator allows users to create custom allocation schemes by * overloading the new_clone(T const& v) and @@ -112,7 +137,7 @@ struct heap_no_copy_allocator * 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 + * @c memcpy, so it has to be used with types that have * standard-layout. */ struct malloc_clone_allocator @@ -134,6 +159,19 @@ struct malloc_clone_allocator } }; +/** + * @internal + */ +template +struct clone_allocator_deleter +{ + template + void operator()(T* object) const + { + A::deallocate_clone(object); + } +}; + /** * @} */ diff --git a/src/bindings/eina_cxx/eina_eo_base_fwd.hh b/src/bindings/eina_cxx/eina_eo_base_fwd.hh new file mode 100644 index 0000000000..989869499e --- /dev/null +++ b/src/bindings/eina_cxx/eina_eo_base_fwd.hh @@ -0,0 +1,10 @@ +#ifndef EINA_EO_BASE_FWD_HH +#define EINA_EO_BASE_FWD_HH + +namespace efl { namespace eo { + +struct base; + +} } + +#endif diff --git a/src/bindings/eina_cxx/eina_list.hh b/src/bindings/eina_cxx/eina_list.hh new file mode 100644 index 0000000000..dbdfea98c0 --- /dev/null +++ b/src/bindings/eina_cxx/eina_list.hh @@ -0,0 +1,330 @@ +#ifndef EINA_LIST_HH_ +#define EINA_LIST_HH_ + +#include + +#include + +namespace efl { namespace eina { + +/** + * @internal + */ +template +struct _ptr_eo_list_iterator : _ptr_list_iterator +{ + typedef _ptr_list_iterator _base_type; + typedef _ptr_eo_list_iterator _self_type; + typedef typename remove_cv::type value_type; + typedef value_type* pointer; + typedef value_type& reference; + + _base_type& _base() { return *this; } + _base_type const& _base() const { return *this; } + + _ptr_eo_list_iterator(_base_type const& base) : _base_type(base) {} + _ptr_eo_list_iterator() {} + explicit _ptr_eo_list_iterator(Eina_List* list, Eina_List* node) + : _base_type(list, node) + { + } + _ptr_eo_list_iterator(_ptr_eo_list_iterator const& other) + : _base_type(static_cast<_base_type const&>(other)) + { + } + _self_type& operator=(_self_type const& other) + { + this->_base_type::operator=(other); + return *this; + } + + _self_type& operator++() + { + ++_base(); + return *this; + } + _self_type operator++(int) + { + _self_type tmp(*this); + ++_base(); + return tmp; + } + _self_type& operator--() + { + --_base(); + return *this; + } + _self_type operator--(int) + { + _self_type tmp(*this); + --_base(); + return tmp; + } + reference operator*() const + { + void* data = reinterpret_cast(&this->_node->data); + return *static_cast(data); + } + pointer operator->() const + { + return &**this; + } + + using _base_type::native_handle; +}; + +template +class list : ptr_list::value + , heap_no_copy_allocator, CloneAllocator>::type> +{ + typedef ptr_list::value + , heap_no_copy_allocator, CloneAllocator>::type> _base_type; +public: + typedef typename _base_type::value_type value_type; + typedef typename _base_type::reference reference; + typedef typename _base_type::const_reference const_reference; + typedef typename _base_type::const_iterator const_iterator; + typedef typename _base_type::iterator iterator; + typedef typename _base_type::pointer pointer; + typedef typename _base_type::const_pointer const_pointer; + typedef typename _base_type::size_type size_type; + typedef typename _base_type::difference_type difference_type; + typedef typename _base_type::clone_allocator_type clone_allocator_type; + + typedef typename _base_type::reverse_iterator reverse_iterator; + typedef typename _base_type::const_reverse_iterator const_reverse_iterator; + + using _base_type::_base_type; + using _base_type::clear; + using _base_type::size; + using _base_type::empty; + using _base_type::get_clone_allocator; + using _base_type::push_back; + using _base_type::push_front; + using _base_type::pop_back; + using _base_type::pop_front; + using _base_type::insert; + using _base_type::erase; + using _base_type::assign; + using _base_type::back; + using _base_type::front; + using _base_type::begin; + using _base_type::end; + using _base_type::rbegin; + using _base_type::rend; + using _base_type::cbegin; + using _base_type::cend; + using _base_type::crbegin; + using _base_type::crend; + using _base_type::ibegin; + using _base_type::iend; + using _base_type::cibegin; + using _base_type::ciend; + using _base_type::swap; + using _base_type::max_size; + using _base_type::native_handle; + using _base_type::accessor; +}; + +template +class list::value>::type> + : ptr_list::value + , eo_clone_allocator, CloneAllocator>::type> +{ + typedef ptr_list::value + , eo_clone_allocator, CloneAllocator>::type> _base_type; + typedef list _self_type; +public: + typedef T value_type; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef _ptr_eo_list_iterator const_iterator; + typedef _ptr_eo_list_iterator iterator; + typedef value_type* pointer; + typedef value_type const* const_pointer; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename _base_type::clone_allocator_type clone_allocator_type; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + explicit list(Eina_List* handle) + : _base_type(handle) {} + list(clone_allocator_type alloc) : _base_type(alloc) {} + list() {} + list(size_type n, const_reference t) + { + while(n--) + push_back(t); + } + template + list(InputIterator i, InputIterator const& j + , clone_allocator_type const& alloc = clone_allocator_type() + , typename eina::enable_if::value>::type* = 0) + : _base_type(alloc) + { + while(i != j) + { + push_back(*i); + ++i; + } + } + list(list const& other) + : _base_type() + { + insert(end(), other.begin(), other.end()); + } + ~list() + { + } + list& operator=(listconst& other) + { + clear(); + insert(end(), other.begin(), other.end()); + return *this; + } + + using _base_type::clear; + using _base_type::size; + using _base_type::empty; + using _base_type::get_clone_allocator; + using _base_type::pop_back; + using _base_type::pop_front; + + void push_back(const_reference w) + { + this->_base_type::push_back(* ::eo_ref(w._eo_ptr())); + } + void push_front(const_reference w) + { + this->_base_type::push_front(* ::eo_ref(w._eo_ptr())); + } + iterator insert(iterator i, const_reference v) + { + return this->_base_type::insert(i, * ::eo_ref(v._eo_ptr())); + } + iterator insert(iterator i, size_t n, const_reference v) + { + return this->_base_type::insert(i, n, * ::eo_ref(v._eo_ptr())); + } + template + iterator insert(iterator p, InputIterator i, InputIterator j + , typename eina::enable_if::value>::type* = 0) + { + iterator r = p; + if(i != j) + { + r = insert(p, *i); + ++i; + } + while(i != j) + { + insert(p, *i); + ++i; + } + return r; + } + iterator erase(iterator p) + { + return _base_type::erase(p); + } + iterator erase(iterator i, iterator j) + { + return _base_type::erase(i, j); + } + template + void assign(InputIterator i, InputIterator j + , typename eina::enable_if::value>::type* = 0) + { + clear(); + insert(end(), i, j); + } + + void assign(size_type n, value_type const& t) + { + clear(); + insert(end(), n, t); + } + + reference front() + { + return *static_cast(static_cast(&native_handle()->data)); + } + reference back() + { + return *static_cast(static_cast(&eina_list_last(native_handle())->data)); + } + const_reference front() const { return const_cast<_self_type*>(this)->front(); } + const_reference back() const { return const_cast<_self_type*>(this)->back(); } + iterator begin() + { + return iterator(native_handle(), native_handle()); + } + iterator end() + { + return iterator(native_handle(), nullptr); + } + const_iterator begin() const + { + return const_cast<_self_type*>(this)->begin(); + } + const_iterator end() const + { + return const_cast<_self_type*>(this)->end(); + } + const_iterator cbegin() const + { + return begin(); + } + const_iterator cend() const + { + return end(); + } + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rbegin() const + { + return const_cast<_self_type*>(this)->rbegin(); + } + const_reverse_iterator rend() const + { + return const_cast<_self_type*>(this)->rend(); + } + const_reverse_iterator crbegin() const + { + return rbegin(); + } + const_reverse_iterator crend() const + { + return rend(); + } + using _base_type::swap; + using _base_type::max_size; + using _base_type::native_handle; + + friend bool operator==(list const& rhs, list const& lhs) + { + return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); + } +}; + +template +bool operator!=(list const& rhs, list const& lhs) +{ + return !(rhs == lhs); +} + +} } + +#endif diff --git a/src/bindings/eina_cxx/eina_ptrarray.hh b/src/bindings/eina_cxx/eina_ptrarray.hh index 175a9710a7..0b994e94ae 100644 --- a/src/bindings/eina_cxx/eina_ptrarray.hh +++ b/src/bindings/eina_cxx/eina_ptrarray.hh @@ -445,6 +445,8 @@ public: 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. */ + typedef std::unique_ptr > _unique_ptr; + /** * @brief Default constructor. Create an empty array. * @@ -452,6 +454,10 @@ public: */ ptr_array() {} + explicit ptr_array(Eina_Array* handle) : _base_type(handle) {} + + explicit ptr_array(clone_allocator_type alloc) : _base_type(alloc) {} + /** * @brief Construct an array object with @p n copies of @p t. * @param n Number of elements. @@ -609,7 +615,7 @@ public: */ void push_back(pointer p) { - std::unique_ptr p1(p); + _unique_ptr p1(p); push_back(p1); } @@ -625,7 +631,8 @@ public: * @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) + template + void push_back(std::unique_ptr& p) { if(eina_array_push(this->_impl._array, p.get())) p.release(); @@ -678,7 +685,7 @@ public: */ iterator insert(iterator i, pointer pv) { - std::unique_ptr p(pv); + _unique_ptr p(pv); return insert(i, p); } @@ -699,7 +706,8 @@ public: * @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) + template + iterator insert(iterator i, std::unique_ptr& p) { std::size_t j = i.native_handle() - this->_impl._array->data @@ -712,7 +720,7 @@ public: this->_impl._array->data + j + 1 , this->_impl._array->data + j , (size_ - j)*sizeof(void*)); - // PRE: Q:[j, size) = [j+1, size+1) + // PRE: Q:[j, size_) = [j+1, size_+1) pointer* data = static_cast (static_cast(this->_impl._array->data)); data[j] = p.get(); diff --git a/src/bindings/eina_cxx/eina_ptrlist.hh b/src/bindings/eina_cxx/eina_ptrlist.hh index 5dafed202c..c0f8776f80 100644 --- a/src/bindings/eina_cxx/eina_ptrlist.hh +++ b/src/bindings/eina_cxx/eina_ptrlist.hh @@ -1,15 +1,17 @@ -#ifndef EINA_LIST_HH_ -#define EINA_LIST_HH_ +#ifndef EINA_PTRLIST_HH_ +#define EINA_PTRLIST_HH_ #include #include #include #include #include +#include #include #include #include +#include /** * @addtogroup Eina_Cxx_Containers_Group @@ -560,6 +562,8 @@ public: 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. */ + typedef std::unique_ptr > _unique_ptr; + /** * @brief Default constructor. Create an empty list. * @@ -567,6 +571,12 @@ public: */ ptr_list() {} + ptr_list(Eina_List* handle) : _base_type(handle) {} + + ptr_list(clone_allocator_type alloc) + : _base_type(alloc) + {} + /** * @brief Construct an list object with @p n copies of @p t. * @param n Number of elements. @@ -725,7 +735,7 @@ public: */ void push_back(pointer p) { - std::unique_ptr p1(p); + _unique_ptr p1(p); push_back(p1); } @@ -740,7 +750,8 @@ public: * @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) + template + void push_back(std::unique_ptr& p) { Eina_List* new_list = eina_list_append(this->_impl._list, p.get()); if(new_list) @@ -761,7 +772,7 @@ public: */ void push_front(const_reference a) { - push_front(this->new_clone(a)); + push_front(this->_new_clone(a)); } /** @@ -777,7 +788,7 @@ public: */ void push_front(pointer p) { - std::unique_ptr p1(p); + _unique_ptr p1(p); push_front(p1); } @@ -792,7 +803,8 @@ public: * @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) + template + void push_front(std::unique_ptr& p) { Eina_List* new_list = eina_list_prepend(this->_impl._list, p.get()); if(new_list) @@ -857,7 +869,7 @@ public: */ iterator insert(iterator i, pointer pv) { - std::unique_ptr p(pv); + _unique_ptr p(pv); return insert(i, p); } @@ -878,7 +890,8 @@ public: * @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) + template + iterator insert(iterator i, std::unique_ptr& p) { this->_impl._list = _eina_list_prepend_relative_list (this->_impl._list, p.get(), i.native_handle()); @@ -967,7 +980,7 @@ public: iterator r = p; if(i != j) { - r = insert(p, *i); + r = insert(p, this->_new_clone(*i)); ++i; } while(i != j) @@ -1442,7 +1455,6 @@ void swap(ptr_list& lhs, ptr_list& rhs) { lhs.swap(rhs); } - /** * @} */ diff --git a/src/bindings/eo_cxx/eo_base.hh b/src/bindings/eo_cxx/eo_base.hh index 00b660efc1..4f8cca0d1b 100644 --- a/src/bindings/eo_cxx/eo_base.hh +++ b/src/bindings/eo_cxx/eo_base.hh @@ -47,6 +47,11 @@ struct base detail::unref(_eo_raw); } + base(base const& other) + : _eo_raw( detail::ref(other._eo_ptr()) ) + { + } + /// @brief Assignment operator. /// base& operator=(base const& other) @@ -164,8 +169,19 @@ struct base protected: Eo* _eo_raw; ///< The opaque EO Object. + }; +inline bool operator==(base const& lhs, base const& rhs) +{ + return lhs._eo_ptr() == rhs._eo_ptr(); +} + +inline bool operator!=(base const& lhs, base const& rhs) +{ + return !(lhs == rhs); +} + /// @brief Downcast @p U to @p T. /// /// @param T An EO C++ Class. @@ -206,21 +222,21 @@ struct parent_type /// struct parent_expr { - parent_type operator=(efl::eo::base const& parent) + parent_type operator=(efl::eo::base const& parent) const { return { parent._eo_ptr() }; } - parent_type operator=(std::nullptr_t) + parent_type operator=(std::nullptr_t) const { - return { NULL }; + return { nullptr }; } }; /// /// @brief Placeholder for the parent argument. /// -parent_expr parent = {}; +parent_expr const parent = {}; /// @} diff --git a/src/examples/eina_cxx/Makefile.am b/src/examples/eina_cxx/Makefile.am index 5edbbb89c0..85239b349b 100644 --- a/src/examples/eina_cxx/Makefile.am +++ b/src/examples/eina_cxx/Makefile.am @@ -3,7 +3,7 @@ MAINTAINERCLEANFILES = Makefile.in AM_CXXFLAGS = \ -I$(top_builddir)/src/lib/efl \ -I. \ -@EINA_CXX_CFLAGS@ @CHECK_CFLAGS@ @EINA_CFLAGS@ +@EINA_CXX_CFLAGS@ @CHECK_CFLAGS@ @EINA_CFLAGS@ @EO_CFLAGS@ LDADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LDFLAGS@ @EFL_PTHREAD_LIBS@ diff --git a/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc b/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc index 0d5f9acaad..f52f99af54 100644 --- a/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc +++ b/src/tests/eina_cxx/eina_cxx_test_ptrarray.cc @@ -1,226 +1,479 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + #include "Eina.hh" +#include "Eo.hh" + +#include #include #include +const Eo_Class *simple_class_get(void); +#define MY_CLASS simple_class_get() + +struct wrapper : efl::eo::base +{ + explicit wrapper(Eo* o) + : base(o) {} +}; + START_TEST(eina_cxx_ptrarray_push_back) { efl::eina::eina_init eina_init; - - efl::eina::ptr_array array; - - array.push_back(new int(5)); - array.push_back(new int(10)); - array.push_back(new int(15)); + efl::eo::eo_init eo_init; int result[] = {5, 10, 15}; int rresult[] = {15, 10, 5}; - ck_assert(array.size() == 3); - ck_assert(std::equal(array.begin(), array.end(), result)); - ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + { + efl::eina::ptr_array array; + + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + + ck_assert(array.size() == 3); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } + { + efl::eina::array array; + + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + + ck_assert(array.size() == 3); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } + { + wrapper result_[] = {w1, w2, w3}; + wrapper rresult[] = {w3, w2, w1}; + + efl::eina::array array; + + array.push_back(w1); + array.push_back(w2); + array.push_back(w3); + + ck_assert(array.size() == 3); + ck_assert(std::equal(array.begin(), array.end(), result_)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrarray_pop_back) { efl::eina::eina_init eina_init; - - efl::eina::ptr_array array; - - array.push_back(new int(5)); - array.push_back(new int(10)); - array.push_back(new int(15)); - array.pop_back(); + efl::eo::eo_init eo_init; int result[] = {5, 10}; int rresult[] = {10, 5}; - ck_assert(array.size() == 2); - ck_assert(std::equal(array.begin(), array.end(), result)); - ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + { + efl::eina::ptr_array array; + + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + array.pop_back(); + + ck_assert(array.size() == 2); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } + { + efl::eina::array array; + + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + array.pop_back(); + + ck_assert(array.size() == 2); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } + { + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + efl::eina::array array; + + array.push_back(w1); + array.push_back(w2); + array.push_back(w3); + array.pop_back(); + + wrapper result_[] = {w1, w2}; + wrapper rresult[] = {w2, w1}; + + ck_assert(array.size() == 2); + ck_assert(std::equal(array.begin(), array.end(), result_)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrarray_insert) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_array array; - ck_assert(std::distance(array.begin(), array.end()) == 0u); - ck_assert(std::distance(array.rbegin(), array.rend()) == 0u); + { + efl::eina::ptr_array array; + ck_assert(std::distance(array.begin(), array.end()) == 0u); + ck_assert(std::distance(array.rbegin(), array.rend()) == 0u); - efl::eina::ptr_array::iterator it; + efl::eina::ptr_array::iterator it; - it = array.insert(array.end(), new int(5)); // first element - ck_assert(it != array.end()); - ++it; - ck_assert(it == array.end()); - ck_assert(array[0] == 5); - ck_assert(std::distance(array.begin(), array.end()) == 1u); + it = array.insert(array.end(), new int(5)); // first element + ck_assert(it != array.end()); + ++it; + ck_assert(it == array.end()); + ck_assert(array[0] == 5); + ck_assert(std::distance(array.begin(), array.end()) == 1u); - it = array.insert(array.end(), new int(10)); // equivalent to push_back - ck_assert(it != array.end()); - ++it; - ck_assert(it == array.end()); - ck_assert(array[0] == 5); - ck_assert(array[1] == 10); - ck_assert(std::distance(array.begin(), array.end()) == 2u); + it = array.insert(array.end(), new int(10)); // equivalent to push_back + ck_assert(it != array.end()); + ++it; + ck_assert(it == array.end()); + ck_assert(array[0] == 5); + ck_assert(array[1] == 10); + ck_assert(std::distance(array.begin(), array.end()) == 2u); - it = array.insert(array.begin(), new int(15)); // equivalent to push_front - ck_assert(it == array.begin()); + it = array.insert(array.begin(), new int(15)); // equivalent to push_front + ck_assert(it == array.begin()); - ck_assert(array[1] == 5); - ck_assert(array[2] == 10); - ck_assert(array[0] == 15); - ck_assert(std::distance(array.begin(), array.end()) == 3u); + ck_assert(array[1] == 5); + ck_assert(array[2] == 10); + ck_assert(array[0] == 15); + ck_assert(std::distance(array.begin(), array.end()) == 3u); - array.insert(array.end() - 1, new int(20)); // insert before the last element - ck_assert(array[0] == 15); - ck_assert(array[1] == 5); - ck_assert(array[2] == 20); - ck_assert(array[3] == 10); - ck_assert(std::distance(array.begin(), array.end()) == 4u); + array.insert(array.end() - 1, new int(20)); // insert before the last element + ck_assert(array[0] == 15); + ck_assert(array[1] == 5); + ck_assert(array[2] == 20); + ck_assert(array[3] == 10); + ck_assert(std::distance(array.begin(), array.end()) == 4u); - int result[] = {15, 5, 20, 10}; - int rresult[] = {10, 20, 5, 15}; + int result[] = {15, 5, 20, 10}; + int rresult[] = {10, 20, 5, 15}; - ck_assert(array.size() == 4); - ck_assert(std::distance(array.begin(), array.end()) == 4u); - ck_assert(std::distance(array.rbegin(), array.rend()) == 4u); - ck_assert(std::equal(array.begin(), array.end(), result)); - ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + ck_assert(array.size() == 4); + ck_assert(std::distance(array.begin(), array.end()) == 4u); + ck_assert(std::distance(array.rbegin(), array.rend()) == 4u); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); - efl::eina::ptr_array array2; - it = array2.insert(array2.end(), array.begin(), array.end()); - ck_assert(it == array2.begin()); - ck_assert(array == array2); + efl::eina::ptr_array array2; + it = array2.insert(array2.end(), array.begin(), array.end()); + ck_assert(it == array2.begin()); + ck_assert(array == array2); - efl::eina::ptr_array array3; - array3.push_back(1); - it = array3.insert(array3.end(), array.begin(), array.end()); - ck_assert(array3.size() == 5); - ck_assert(array3.front() == 1); - it = array3.begin(); - ++it; - ck_assert(std::equal(it, array3.end(), array.begin())); + efl::eina::ptr_array array3; + array3.push_back(1); + it = array3.insert(array3.end(), array.begin(), array.end()); + ck_assert(array3.size() == 5); + ck_assert(array3.front() == 1); + it = array3.begin(); + ++it; + ck_assert(std::equal(it, array3.end(), array.begin())); - efl::eina::ptr_array array4; - array4.push_back(1); - it = array4.insert(array4.begin(), array.begin(), array.end()); - ck_assert(array4.size() == 5); - ck_assert(array4.back() == 1); - ck_assert(std::equal(array.begin(), array.end(), array4.begin())); + efl::eina::ptr_array array4; + array4.push_back(1); + it = array4.insert(array4.begin(), array.begin(), array.end()); + ck_assert(array4.size() == 5); + ck_assert(array4.back() == 1); + ck_assert(std::equal(array.begin(), array.end(), array4.begin())); + } + { + wrapper const w0(eo_add(MY_CLASS, NULL)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + wrapper const w4(eo_add(MY_CLASS, NULL)); + + efl::eina::array array; + ck_assert(std::distance(array.begin(), array.end()) == 0u); + ck_assert(std::distance(array.rbegin(), array.rend()) == 0u); + + efl::eina::array::iterator it; + + it = array.insert(array.end(), w1); // first element + ck_assert(it != array.end()); + ++it; + ck_assert(it == array.end()); + ck_assert(array[0] == w1); + ck_assert(std::distance(array.begin(), array.end()) == 1u); + + it = array.insert(array.end(), w2); // equivalent to push_back + ck_assert(it != array.end()); + ++it; + ck_assert(it == array.end()); + ck_assert(array[0] == w1); + ck_assert(array[1] == w2); + ck_assert(std::distance(array.begin(), array.end()) == 2u); + + it = array.insert(array.begin(), w3); // equivalent to push_front + ck_assert(it == array.begin()); + + ck_assert(array[1] == w1); + ck_assert(array[2] == w2); + ck_assert(array[0] == w3); + ck_assert(std::distance(array.begin(), array.end()) == 3u); + + array.insert(array.end() - 1, w4); // insert before the last element + ck_assert(array[0] == w3); + ck_assert(array[1] == w1); + ck_assert(array[2] == w4); + ck_assert(array[3] == w2); + ck_assert(std::distance(array.begin(), array.end()) == 4u); + + wrapper result[] = {w3, w1, w4, w2}; + wrapper rresult[] = {w2, w4, w1, w3}; + + ck_assert(array.size() == 4); + ck_assert(std::distance(array.begin(), array.end()) == 4u); + ck_assert(std::distance(array.rbegin(), array.rend()) == 4u); + ck_assert(std::equal(array.begin(), array.end(), result)); + ck_assert(std::equal(array.rbegin(), array.rend(), rresult)); + + efl::eina::array array2; + it = array2.insert(array2.end(), array.begin(), array.end()); + ck_assert(it == array2.begin()); + ck_assert(array == array2); + + efl::eina::array array3; + array3.push_back(w0); + it = array3.insert(array3.end(), array.begin(), array.end()); + ck_assert(array3.size() == 5); + ck_assert(array3.front() == w0); + it = array3.begin(); + ++it; + ck_assert(std::equal(it, array3.end(), array.begin())); + + efl::eina::array array4; + array4.push_back(w0); + it = array4.insert(array4.begin(), array.begin(), array.end()); + ck_assert(array4.size() == 5); + ck_assert(array4.back() == w0); + ck_assert(std::equal(array.begin(), array.end(), array4.begin())); + } } END_TEST START_TEST(eina_cxx_ptrarray_constructors) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_array array1; - ck_assert(array1.empty()); + wrapper const w1(eo_add(MY_CLASS, NULL)); - efl::eina::ptr_array array2(10, 5); - ck_assert(array2.size() == 10); - ck_assert(std::find_if(array2.begin(), array2.end() - , std::not1(std::bind1st(std::equal_to(), 5))) == array2.end()); + { + efl::eina::ptr_array array1; + ck_assert(array1.empty()); - efl::eina::ptr_array array3(array2); - ck_assert(array2 == array3); + efl::eina::ptr_array array2(10, 5); + ck_assert(array2.size() == 10); + ck_assert(std::find_if(array2.begin(), array2.end() + , [](int i) { return i != 5; }) == array2.end()); - efl::eina::ptr_array array4 - (array2.begin(), array2.end()); - ck_assert(array2 == array4); + efl::eina::ptr_array array3(array2); + ck_assert(array2 == array3); + + efl::eina::ptr_array array4 + (array2.begin(), array2.end()); + ck_assert(array2 == array4); + } + { + efl::eina::array array1; + ck_assert(array1.empty()); + + efl::eina::array array2(10, w1); + ck_assert(array2.size() == 10); + ck_assert(std::find_if(array2.begin(), array2.end() + , [w1](wrapper i) { return i != w1; }) == array2.end()); + + efl::eina::array array3(array2); + ck_assert(array2 == array3); + + efl::eina::array array4 + (array2.begin(), array2.end()); + ck_assert(array2 == array4); + } } END_TEST START_TEST(eina_cxx_ptrarray_erase) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_array array1; - array1.push_back(new int(5)); - array1.push_back(new int(10)); - array1.push_back(new int(15)); - array1.push_back(new int(20)); - array1.push_back(new int(25)); - array1.push_back(new int(30)); + { + efl::eina::ptr_array array1; + array1.push_back(new int(5)); + array1.push_back(new int(10)); + array1.push_back(new int(15)); + array1.push_back(new int(20)); + array1.push_back(new int(25)); + array1.push_back(new int(30)); - int result[] = {5, 10, 15, 20, 25, 30}; - int rresult[] = {30, 25, 20, 15, 10, 5}; - ck_assert(std::equal(array1.begin(), array1.end(), result)); - ck_assert(std::equal(array1.rbegin(), array1.rend(), rresult)); + int result[] = {5, 10, 15, 20, 25, 30}; + int rresult[] = {30, 25, 20, 15, 10, 5}; + ck_assert(std::equal(array1.begin(), array1.end(), result)); + ck_assert(std::equal(array1.rbegin(), array1.rend(), rresult)); - efl::eina::ptr_array::iterator it = array1.erase(array1.begin()); - ck_assert(it == array1.begin()); - ck_assert(array1.size() == 5); - ck_assert(array1.front() == 10); + efl::eina::ptr_array::iterator it = array1.erase(array1.begin()); + ck_assert(it == array1.begin()); + ck_assert(array1.size() == 5); + ck_assert(array1.front() == 10); - ck_assert(std::equal(array1.begin(), array1.end(), &result[1])); + ck_assert(std::equal(array1.begin(), array1.end(), &result[1])); - it = array1.erase(array1.begin() + 1); - ck_assert(*it == 20); - ck_assert(array1.size() == 4); + it = array1.erase(array1.begin() + 1); + ck_assert(*it == 20); + ck_assert(array1.size() == 4); - it = array1.erase(array1.end() - 1); - ck_assert(it == array1.end()); - ck_assert(array1.size() == 3); - ck_assert(array1.back() == 25); + it = array1.erase(array1.end() - 1); + ck_assert(it == array1.end()); + ck_assert(array1.size() == 3); + ck_assert(array1.back() == 25); - it = array1.erase(array1.begin() + 1, array1.end() - 1); - ck_assert(it == array1.end() - 1); - ck_assert(array1.size() == 2); - ck_assert(array1.front() == 10); - ck_assert(array1.back() == 25); + it = array1.erase(array1.begin() + 1, array1.end() - 1); + ck_assert(it == array1.end() - 1); + ck_assert(array1.size() == 2); + ck_assert(array1.front() == 10); + ck_assert(array1.back() == 25); + } + { + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + wrapper const w4(eo_add(MY_CLASS, NULL)); + wrapper const w5(eo_add(MY_CLASS, NULL)); + wrapper const w6(eo_add(MY_CLASS, NULL)); + + efl::eina::array array1; + + array1.push_back(w1); + array1.push_back(w2); + array1.push_back(w3); + array1.push_back(w4); + array1.push_back(w5); + array1.push_back(w6); + + wrapper result_[] = {w1, w2, w3, w4, w5, w6}; + wrapper rresult[] = {w6, w5, w4, w3, w2, w1}; + ck_assert(std::equal(array1.begin(), array1.end(), result_)); + ck_assert(std::equal(array1.rbegin(), array1.rend(), rresult)); + + efl::eina::array::iterator it = array1.erase(array1.begin()); + ck_assert(it == array1.begin()); + ck_assert(array1.size() == 5); + ck_assert(array1.front() == w2); + + ck_assert(std::equal(array1.begin(), array1.end(), &result_[1])); + + it = array1.erase(array1.begin() + 1); + ck_assert(*it == w4); + ck_assert(array1.size() == 4); + + it = array1.erase(array1.end() - 1); + ck_assert(it == array1.end()); + ck_assert(array1.size() == 3); + ck_assert(array1.back() == w5); + + it = array1.erase(array1.begin() + 1, array1.end() - 1); + ck_assert(it == array1.end() - 1); + ck_assert(array1.size() == 2); + ck_assert(array1.front() == w2); + ck_assert(array1.back() == w5); + } } END_TEST START_TEST(eina_cxx_ptrarray_range) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_array array; - array.push_back(new int(5)); - array.push_back(new int(10)); - array.push_back(new int(15)); - array.push_back(new int(20)); - array.push_back(new int(25)); - array.push_back(new int(30)); + { + efl::eina::ptr_array array; + array.push_back(new int(5)); + array.push_back(new int(10)); + array.push_back(new int(15)); + array.push_back(new int(20)); + array.push_back(new int(25)); + array.push_back(new int(30)); - efl::eina::range_ptr_array range_array(array); + efl::eina::range_ptr_array range_array(array); - ck_assert(range_array.size() == 6u); + ck_assert(range_array.size() == 6u); - int result[] = {5, 10, 15, 20, 25, 30}; - int rresult[] = {30, 25, 20, 15, 10, 5}; - ck_assert(std::equal(range_array.begin(), range_array.end(), result)); - ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); + int result[] = {5, 10, 15, 20, 25, 30}; + int rresult[] = {30, 25, 20, 15, 10, 5}; + ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); - efl::eina::range_ptr_array const_range_array(array); + efl::eina::range_ptr_array const_range_array(array); - ck_assert(const_range_array.size() == 6u); - ck_assert(std::equal(range_array.begin(), range_array.end(), result)); - ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); + ck_assert(const_range_array.size() == 6u); + ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); - *range_array.begin() = 0; - ck_assert(*const_range_array.begin() == 0); - ck_assert(*array.begin() == 0); -} -END_TEST + *range_array.begin() = 0; + ck_assert(*const_range_array.begin() == 0); + ck_assert(*array.begin() == 0); + } -START_TEST(eina_cxx_ptrarray_from_c) -{ - efl::eina::eina_init eina_init; + { + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + wrapper const w4(eo_add(MY_CLASS, NULL)); + wrapper const w5(eo_add(MY_CLASS, NULL)); + wrapper const w6(eo_add(MY_CLASS, NULL)); - Eina_Array *c_array = eina_array_new(3); - ck_assert(!!c_array); - efl::eina::range_ptr_array range_array(c_array); + efl::eina::array array; + array.push_back(w1); + array.push_back(w2); + array.push_back(w3); + array.push_back(w4); + array.push_back(w5); + array.push_back(w6); - eina_array_free(c_array); + // efl::eina::range_array range_array(array); + + // ck_assert(range_array.size() == 6u); + + // wrapper result[] = {5, 10, 15, 20, 25, 30}; + // wrapper rresult[] = {30, 25, 20, 15, 10, 5}; + // ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + // ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); + + // efl::eina::range_array const_range_array(array); + + // ck_assert(const_range_array.size() == 6u); + // ck_assert(std::equal(range_array.begin(), range_array.end(), result)); + // ck_assert(std::equal(range_array.rbegin(), range_array.rend(), rresult)); + + // *range_array.begin() = 0; + // ck_assert(*const_range_array.begin() == 0); + // ck_assert(*array.begin() == 0); + } } END_TEST @@ -233,5 +486,4 @@ eina_test_ptrarray(TCase* tc) tcase_add_test(tc, eina_cxx_ptrarray_constructors); tcase_add_test(tc, eina_cxx_ptrarray_erase); tcase_add_test(tc, eina_cxx_ptrarray_range); - tcase_add_test(tc, eina_cxx_ptrarray_from_c); } diff --git a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc index f422cdec60..8804310c01 100644 --- a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc +++ b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc @@ -1,140 +1,366 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + #include "Eina.hh" +#include "Eo.hh" + +#include #include +#include #include +const Eo_Class *simple_class_get(void); +#define MY_CLASS simple_class_get() + +static void +_constructor(Eo *obj, void *class_data EINA_UNUSED) +{ + eo_do_super(obj, MY_CLASS, eo_constructor()); +} + +static void +_destructor(Eo *obj, void *class_data EINA_UNUSED) +{ + eo_do_super(obj, MY_CLASS, eo_destructor()); +} + +static Eo_Op_Description op_descs[] = { + EO_OP_FUNC_OVERRIDE(reinterpret_cast(&eo_constructor), reinterpret_cast(&_constructor)) + , EO_OP_FUNC_OVERRIDE(reinterpret_cast(&eo_destructor), reinterpret_cast(&_destructor)) + , EO_OP_SENTINEL +}; + +static const Eo_Class_Description class_desc = { + EO_VERSION, + "Simple", + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(op_descs), + NULL, + 0, + 0, + 0 +}; + +EO_DEFINE_CLASS(simple_class_get, &class_desc, EO_CLASS, NULL); + +struct wrapper : efl::eo::base +{ + explicit wrapper(Eo* o) + : base(o) {} +}; + START_TEST(eina_cxx_ptrlist_push_back) { efl::eina::eina_init eina_init; - - efl::eina::ptr_list list; - - list.push_back(new int(5)); - list.push_back(new int(10)); - list.push_back(new int(15)); + efl::eo::eo_init eo_init; int result[] = {5, 10, 15}; int rresult[] = {15, 10, 5}; - ck_assert(list.size() == 3); - ck_assert(std::equal(list.begin(), list.end(), result)); - ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + { + efl::eina::ptr_list list; + + list.push_back(new int(5)); + list.push_back(new int(10)); + list.push_back(new int(15)); + + ck_assert(list.size() == 3); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + efl::eina::list list; + list.push_back(new int(5)); + list.push_back(new int(10)); + list.push_back(new int(15)); + + ck_assert(list.size() == 3); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + wrapper result[] = {w1, w2, w3}; + wrapper rresult[] = {w3, w2, w1}; + + efl::eina::list list; + list.push_back(w1); + list.push_back(w2); + list.push_back(w3); + + ck_assert(list.size() == 3); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrlist_pop_back) { efl::eina::eina_init eina_init; - - efl::eina::ptr_list list; - - list.push_back(new int(5)); - list.push_back(new int(10)); - list.push_back(new int(15)); - list.pop_back(); + efl::eo::eo_init eo_init; int result[] = {5, 10}; int rresult[] = {10, 5}; - ck_assert(list.size() == 2); - ck_assert(std::equal(list.begin(), list.end(), result)); - ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + { + efl::eina::ptr_list list; + + list.push_back(new int(5)); + list.push_back(new int(10)); + list.push_back(new int(15)); + list.pop_back(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + efl::eina::list list; + + list.push_back(new int(5)); + list.push_back(new int(10)); + list.push_back(new int(15)); + list.pop_back(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + wrapper result[] = {w1, w2}; + wrapper rresult[] = {w2, w1}; + + efl::eina::list list; + + list.push_back(w1); + list.push_back(w2); + list.push_back(w3); + list.pop_back(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrlist_push_front) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_list list; + { + efl::eina::ptr_list list; - list.push_front(new int(5)); - list.push_front(new int(10)); - list.push_front(new int(15)); + list.push_front(new int(5)); + list.push_front(new int(10)); + list.push_front(new int(15)); - int result[] = {15, 10, 5}; - int rresult[] = {5, 10, 15}; + int result[] = {15, 10, 5}; + int rresult[] = {5, 10, 15}; - ck_assert(list.size() == 3); - ck_assert(std::equal(list.begin(), list.end(), result)); - ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + ck_assert(list.size() == 3); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + efl::eina::list list; + + list.push_front(w1); + list.push_front(w2); + list.push_front(w3); + + wrapper result[] = {w3, w2, w1}; + wrapper rresult[] = {w1, w2, w3}; + + ck_assert(list.size() == 3); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrlist_pop_front) { efl::eina::eina_init eina_init; - - efl::eina::ptr_list list; - - list.push_front(new int(5)); - list.push_front(new int(10)); - list.push_front(new int(15)); - list.pop_front(); + efl::eo::eo_init eo_init; int result[] = {10, 5}; int rresult[] = {5, 10}; - ck_assert(list.size() == 2); - ck_assert(std::equal(list.begin(), list.end(), result)); - ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + + { + efl::eina::ptr_list list; + + list.push_front(new int(5)); + list.push_front(new int(10)); + list.push_front(new int(15)); + list.pop_front(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + efl::eina::list list; + + list.push_front(new int(5)); + list.push_front(new int(10)); + list.push_front(new int(15)); + list.pop_front(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } + { + wrapper result[] = {w2, w1}; + wrapper rresult[] = {w1, w2}; + + efl::eina::list list; + + list.push_front(w1); + list.push_front(w2); + list.push_front(w3); + list.pop_front(); + + ck_assert(list.size() == 2); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + } } END_TEST START_TEST(eina_cxx_ptrlist_insert) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_list list; + { + efl::eina::ptr_list list; - efl::eina::ptr_list::iterator it; + efl::eina::ptr_list::iterator it; - it = list.insert(list.end(), new int(5)); // first element - ck_assert(it != list.end()); - ++it; - ck_assert(it == list.end()); + it = list.insert(list.end(), new int(5)); // first element + ck_assert(it != list.end()); + ++it; + ck_assert(it == list.end()); - it = list.insert(list.end(), new int(10)); // equivalent to push_back - ck_assert(it != list.end()); - ++it; - ck_assert(it == list.end()); + it = list.insert(list.end(), new int(10)); // equivalent to push_back + ck_assert(it != list.end()); + ++it; + ck_assert(it == list.end()); - it = list.insert(list.begin(), new int(15)); // equivalent to push_front - ck_assert(it == list.begin()); + it = list.insert(list.begin(), new int(15)); // equivalent to push_front + ck_assert(it == list.begin()); - it = list.end(); - --it; - list.insert(it, new int(20)); // insert before the last element + it = list.end(); + --it; + list.insert(it, new int(20)); // insert before the last element - int result[] = {15, 5, 20, 10}; - int rresult[] = {10, 20, 5, 15}; + int result[] = {15, 5, 20, 10}; + int rresult[] = {10, 20, 5, 15}; - ck_assert(list.size() == 4); - ck_assert(std::equal(list.begin(), list.end(), result)); - ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + ck_assert(list.size() == 4); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); - efl::eina::ptr_list list2; - it = list2.insert(list2.end(), list.begin(), list.end()); - ck_assert(it == list2.begin()); - ck_assert(list == list2); + efl::eina::ptr_list list2; + it = list2.insert(list2.end(), list.begin(), list.end()); + ck_assert(it == list2.begin()); + ck_assert(list == list2); - efl::eina::ptr_list list3; - list3.push_back(1); - it = list3.insert(list3.end(), list.begin(), list.end()); - ck_assert(list3.size() == 5); - ck_assert(list3.front() == 1); - it = list3.begin(); - ++it; - ck_assert(std::equal(it, list3.end(), list.begin())); + efl::eina::ptr_list list3; + list3.push_back(1); + it = list3.insert(list3.end(), list.begin(), list.end()); + ck_assert(list3.size() == 5); + ck_assert(list3.front() == 1); + it = list3.begin(); + ++it; + ck_assert(std::equal(it, list3.end(), list.begin())); - efl::eina::ptr_list list4; - list4.push_back(1); - it = list4.insert(list4.begin(), list.begin(), list.end()); - ck_assert(list4.size() == 5); - ck_assert(list4.back() == 1); - ck_assert(std::equal(list.begin(), list.end(), list4.begin())); + efl::eina::ptr_list list4; + list4.push_back(1); + it = list4.insert(list4.begin(), list.begin(), list.end()); + ck_assert(list4.size() == 5); + ck_assert(list4.back() == 1); + ck_assert(std::equal(list.begin(), list.end(), list4.begin())); + } + { + wrapper const w0(eo_add(MY_CLASS, NULL)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + wrapper const w4(eo_add(MY_CLASS, NULL)); + + efl::eina::list list; + + efl::eina::list::iterator it; + + it = list.insert(list.end(), w1); // first element + ck_assert(it != list.end()); + ++it; + ck_assert(it == list.end()); + + it = list.insert(list.end(), w2); // equivalent to push_back + ck_assert(it != list.end()); + ++it; + ck_assert(it == list.end()); + + it = list.insert(list.begin(), w3); // equivalent to push_front + ck_assert(it == list.begin()); + + it = list.end(); + --it; + list.insert(it, w4); // insert before the last element + + wrapper result[] = {w3, w1, w4, w2}; + wrapper rresult[] = {w2, w4, w1, w3}; + + ck_assert(list.size() == 4); + ck_assert(std::equal(list.begin(), list.end(), result)); + ck_assert(std::equal(list.rbegin(), list.rend(), rresult)); + + efl::eina::list list2; + it = list2.insert(list2.end(), list.begin(), list.end()); + ck_assert(it == list2.begin()); + ck_assert(list == list2); + + efl::eina::list list3; + list3.push_back(w0); + it = list3.insert(list3.end(), list.begin(), list.end()); + ck_assert(list3.size() == 5); + ck_assert(list3.front() == w0); + it = list3.begin(); + ++it; + ck_assert(std::equal(it, list3.end(), list.begin())); + + efl::eina::list list4; + list4.push_back(w0); + it = list4.insert(list4.begin(), list.begin(), list.end()); + ck_assert(list4.size() == 5); + ck_assert(list4.back() == w0); + ck_assert(std::equal(list.begin(), list.end(), list4.begin())); + } } END_TEST @@ -154,21 +380,50 @@ END_TEST START_TEST(eina_cxx_ptrlist_constructors) { efl::eina::eina_init eina_init; + efl::eo::eo_init eo_init; - efl::eina::ptr_list list1; - ck_assert(list1.empty()); + { + efl::eina::ptr_list list1; + ck_assert(list1.empty()); - efl::eina::ptr_list list2(10, 5); - ck_assert(list2.size() == 10); - ck_assert(std::find_if(list2.begin(), list2.end() - , std::not1(std::bind1st(std::equal_to(), 5))) == list2.end()); + efl::eina::ptr_list list2(10, 5); + ck_assert(list2.size() == 10); + ck_assert(std::find_if(list2.begin(), list2.end() + , std::not1(std::bind1st(std::equal_to(), 5))) == list2.end()); - efl::eina::ptr_list list3(list2); - ck_assert(list2 == list3); + efl::eina::ptr_list list3(list2); + ck_assert(list2 == list3); - efl::eina::ptr_list list4 - (list2.begin(), list2.end()); - ck_assert(list2 == list4); + efl::eina::ptr_list list4 + (list2.begin(), list2.end()); + ck_assert(list2 == list4); + } + { + wrapper const w0(eo_add(MY_CLASS, NULL)); + wrapper const w1(eo_add(MY_CLASS, NULL)); + wrapper const w2(eo_add(MY_CLASS, NULL)); + wrapper const w3(eo_add(MY_CLASS, NULL)); + wrapper const w4(eo_add(MY_CLASS, NULL)); + + efl::eina::list list1; + ck_assert(list1.empty()); + + efl::eina::list list2(10, w1); + ck_assert(list2.size() == 10); + ck_assert(std::find_if(list2.begin(), list2.end() + , [&list2, w2] (wrapper i) + { + return i == w2; + } + ) == list2.end()); + + efl::eina::list list3(list2); + ck_assert(list2 == list3); + + efl::eina::list list4 + (list2.begin(), list2.end()); + ck_assert(list2 == list4); + } } END_TEST @@ -255,43 +510,6 @@ START_TEST(eina_cxx_ptrlist_range) } END_TEST -START_TEST(eina_cxx_ptrlist_from_c) -{ - efl::eina::eina_init eina_init; - Eina_List *c_list = nullptr; - - int values[] = { 11, 22, 33 }; - - c_list = ::eina_list_append(c_list, &values[0]); - ck_assert(!!c_list); - - c_list = ::eina_list_append(c_list, &values[1]); - ck_assert(!!c_list); - - c_list = ::eina_list_append(c_list, &values[2]); - ck_assert(!!c_list); - - const Eina_List* const_c_list = c_list; - const Eina_List* const_c_list_const_ptr = c_list; - - efl::eina::range_ptr_list r0(c_list); - const efl::eina::range_ptr_list r1(c_list); - - efl::eina::range_ptr_list r2(c_list); - efl::eina::range_ptr_list r3(const_c_list); - efl::eina::range_ptr_list r4(const_c_list_const_ptr); - - const efl::eina::range_ptr_list r5(c_list); - const efl::eina::range_ptr_list r6(const_c_list); - const efl::eina::range_ptr_list r7(const_c_list_const_ptr); - - const efl::eina::range_ptr_list r8(c_list); - - c_list = ::eina_list_free(c_list); - ck_assert(!c_list); -} -END_TEST - void eina_test_ptrlist(TCase* tc) { @@ -304,5 +522,4 @@ eina_test_ptrlist(TCase* tc) tcase_add_test(tc, eina_cxx_ptrlist_erase); tcase_add_test(tc, eina_cxx_ptrlist_range); tcase_add_test(tc, eina_cxx_ptrlist_malloc_clone_allocator); - tcase_add_test(tc, eina_cxx_ptrlist_from_c); }