#ifndef EINA_ACCESSOR_HH_ #define EINA_ACCESSOR_HH_ #include #include #include #include #include #include namespace efl { namespace eina { template struct accessor { typedef unsigned int key_type; typedef T mapped_type; typedef T value_type; typedef std::size_t size_type; accessor() : _impl(0) {} explicit accessor(Eina_Accessor* impl) : _impl(impl) { assert(_impl != 0); } accessor(accessor const& other) : _impl(eina_accessor_clone(other._impl)) {} accessor& operator=(accessor const& other) { eina_accessor_free(_impl); _impl = eina_accessor_clone(other._impl); if(!_impl) throw eina::system_error(efl::eina::get_error_code(), "Error cloning accessor"); return *this; } ~accessor() { eina_accessor_free(_impl); } mapped_type& operator[](size_type i) const { assert(_impl != 0); void* p; if(!eina_accessor_data_get(_impl, i, &p)) { eina::error_code ec = efl::eina::get_error_code(); throw eina::system_error(ec, "EFL Eina Error"); } return *static_cast(p); } Eina_Accessor* native_handle() const; void swap(accessor& other) { std::swap(_impl, other._impl); } private: typedef Eina_Accessor*(accessor::*unspecified_bool_type)() const; public: operator unspecified_bool_type() const { return native_handle() ? &accessor::native_handle : 0 ; } private: Eina_Accessor* _impl; }; template void swap(accessor& lhs, accessor& rhs) { lhs.swap(rhs); } 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; accessor_iterator(accessor const& a, unsigned int pos = 0u) : _accessor(a), _index(pos) {} accessor_iterator& operator+=(difference_type i) { _index += i; return *this; } accessor_iterator& operator-=(difference_type i) { _index -= i; return *this; } value_type& operator[](difference_type i) { return _accessor[_index + i]; } accessor_iterator& operator++() { ++_index; return *this; } accessor_iterator& operator--() { --_index; return *this; } accessor_iterator& operator++(int) { accessor_iterator tmp(*this); ++*this; return tmp; } accessor_iterator& operator--(int) { accessor_iterator tmp(*this); --*this; return tmp; } value_type& operator*() const { return _accessor[_index]; } pointer operator->() const { return &**this; } void swap(accessor_iterator& other) { std::swap(_index, other._index); std::swap(_accessor, other._accessor); } private: accessor _accessor; unsigned int _index; template friend bool operator==(accessor_iterator const& lhs, accessor_iterator const& rhs) { return lhs._index == rhs._index; } template friend typename accessor_iterator::difference_type operator-(accessor_iterator const& lhs, accessor_iterator const& rhs) { return lhs._index - rhs._index; } template friend accessor_iterator operator+(accessor_iterator lhs , typename accessor_iterator::difference_type rhs) { lhs._index += rhs; return lhs; } template friend accessor_iterator operator+(typename accessor_iterator::difference_type lhs , accessor_iterator rhs) { return rhs + lhs; } template friend bool operator<(accessor_iterator const& lhs, accessor_iterator const& rhs) { return lhs._index < rhs._index; } template friend bool operator<=(accessor_iterator const& lhs, accessor_iterator const& rhs) { return lhs._index <= rhs._index; } }; template bool operator>=(accessor_iterator const& lhs, accessor_iterator const& rhs) { return !(lhs < rhs); } template bool operator>(accessor_iterator const& lhs, accessor_iterator const& rhs) { return !(lhs <= rhs); } template bool operator!=(accessor_iterator const& lhs, accessor_iterator const& rhs) { return !(lhs == rhs); } template void swap(accessor_iterator& lhs, accessor_iterator& rhs) { lhs.swap(rhs); } } } #endif