#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. */ typedef typename _base_type::native_handle_type native_handle_type; 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::release_native_handle; 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; }; /** * @internal */ struct _eo_array_access_traits : _ptr_array_access_traits { template struct iterator { typedef _ptr_eo_array_iterator type; }; template struct const_iterator : iterator {}; template static T& back(Eina_Array* array) { return *static_cast(static_cast(array->data[size(array)-1])); } template static T const& back(Eina_Array const* array) { return _eo_array_access_traits::back(const_cast(array)); } template static T& front(Eina_Array* array) { return *static_cast(static_cast(array->data[0])); } template static T const& front(Eina_Array const* array) { return _eo_array_access_traits::front(const_cast(array)); } template static typename iterator::type begin(Eina_Array* array) { return _ptr_eo_array_iterator(array->data); } template static typename iterator::type end(Eina_Array* array) { return _ptr_eo_array_iterator(array->data + size(array)); } template static typename const_iterator::type begin(Eina_Array const* array) { return _eo_array_access_traits::begin(const_cast(array)); } template static typename const_iterator::type end(Eina_Array const* array) { return _eo_array_access_traits::end(const_cast(array)); } template static std::reverse_iterator::type> rbegin(Eina_Array* array) { return std::reverse_iterator<_ptr_eo_array_iterator >(_eo_array_access_traits::end(array)); } template static std::reverse_iterator::type> rend(Eina_Array* array) { return std::reverse_iterator<_ptr_eo_array_iterator >(_eo_array_access_traits::begin(array)); } template static std::reverse_iterator::type> rbegin(Eina_Array const* array) { return std::reverse_iterator<_ptr_eo_array_iteratorconst>(_eo_array_access_traits::end(array)); } template static std::reverse_iterator::type> rend(Eina_Array const* array) { return std::reverse_iterator<_ptr_eo_array_iteratorconst>(_eo_array_access_traits::begin(array)); } template static typename const_iterator::type cbegin(Eina_Array const* array) { return _eo_array_access_traits::begin(array); } template static typename const_iterator::type cend(Eina_Array const* array) { return _eo_array_access_traits::end(array); } template static std::reverse_iterator::type> crbegin(Eina_Array const* array) { return _eo_array_access_traits::rbegin(array); } template static std::reverse_iterator::type> crend(Eina_Array const* array) { return _eo_array_access_traits::rend(array); } }; 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. */ typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */ explicit array(native_handle_type 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 end(); } const_reverse_iterator crbegin() const { return rbegin(); } const_reverse_iterator crend() const { return rend(); } eina::iterator ibegin() { return _eo_array_access_traits::ibegin(this->_impl._array); } eina::iterator iend() { return _eo_array_access_traits::iend(this->_impl._array); } eina::iterator ibegin() const { return _eo_array_access_traits::ibegin(this->_impl._array); } eina::iterator iend() const { return _eo_array_access_traits::iend(this->_impl._array); } eina::iterator cibegin() const { return _eo_array_access_traits::cibegin(this->_impl._array); } eina::iterator ciend() const { return _eo_array_access_traits::ciend(this->_impl._array); } using _base_type::swap; using _base_type::max_size; using _base_type::release_native_handle; 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); } template class range_array : range_ptr_array { typedef range_ptr_array _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::reverse_iterator reverse_iterator; typedef typename _base_type::const_reverse_iterator const_reverse_iterator; typedef typename _base_type::native_handle_type native_handle_type; using _base_type::_base_type; using _base_type::size; using _base_type::empty; 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::release_native_handle; using _base_type::native_handle; }; template class range_array::value>::type> : range_ptr_array { typedef range_ptr_array _base_type; typedef range_array _self_type; public: typedef T value_type; typedef value_type& reference; typedef value_type const& const_reference; typedef _ptr_eo_array_iterator const_iterator; typedef _ptr_eo_array_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 std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef typename _base_type::native_handle_type native_handle_type; explicit range_array(native_handle_type handle) : _base_type(handle) {} range_array() {} range_array(range_array const& other) : _base_type(other.native_handle()) { } range_array& operator=(range_arrayconst& other) { _base_type::_handle = other._handle; return *this; } range_array& operator=(range_array&& other) = default; range_array(range_array&& other) = default; using _base_type::size; using _base_type::empty; reference front() { return _eo_array_access_traits::front(native_handle()); } reference back() { return _eo_array_access_traits::back(native_handle()); } 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 _eo_array_access_traits::begin(native_handle()); } iterator end() { return _eo_array_access_traits::end(native_handle()); } 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 _eo_array_access_traits::rbegin(native_handle()); } reverse_iterator rend() { return _eo_array_access_traits::rend(native_handle()); } 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::release_native_handle; using _base_type::native_handle; friend bool operator==(range_array const& rhs, range_array const& lhs) { return rhs.size() == lhs.size() && std::equal(rhs.begin(), rhs.end(), lhs.begin()); } }; template using crange_array = range_array::type>; } } #endif