forked from enlightenment/efl
215 lines
4.5 KiB
C++
215 lines
4.5 KiB
C++
#ifndef EINA_ACCESSOR_HH_
|
|
#define EINA_ACCESSOR_HH_
|
|
|
|
#include <Eina.h>
|
|
#include <eina_error.hh>
|
|
|
|
#include <memory>
|
|
#include <iterator>
|
|
#include <cstdlib>
|
|
#include <cassert>
|
|
|
|
namespace efl { namespace eina {
|
|
|
|
template <typename T>
|
|
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<T> const& other)
|
|
: _impl(eina_accessor_clone(other._impl))
|
|
{}
|
|
accessor<T>& operator=(accessor<T> 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<mapped_type*>(p);
|
|
}
|
|
|
|
Eina_Accessor* native_handle() const;
|
|
|
|
void swap(accessor<T>& other)
|
|
{
|
|
std::swap(_impl, other._impl);
|
|
}
|
|
private:
|
|
typedef Eina_Accessor*(accessor<T>::*unspecified_bool_type)() const;
|
|
public:
|
|
operator unspecified_bool_type() const
|
|
{
|
|
return native_handle() ? &accessor<T>::native_handle : 0 ;
|
|
}
|
|
private:
|
|
Eina_Accessor* _impl;
|
|
};
|
|
|
|
template <typename U>
|
|
void swap(accessor<U>& lhs, accessor<U>& rhs)
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
template <typename T>
|
|
struct accessor_iterator
|
|
{
|
|
typedef T value_type;
|
|
typedef value_type* pointer;
|
|
typedef value_type& reference;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef std::random_access_iterator_tag iterator_category;
|
|
|
|
accessor_iterator(accessor<T> const& a, unsigned int pos = 0u)
|
|
: _accessor(a), _index(pos)
|
|
{}
|
|
|
|
accessor_iterator<T>& operator+=(difference_type i)
|
|
{
|
|
_index += i;
|
|
return *this;
|
|
}
|
|
accessor_iterator<T>& operator-=(difference_type i)
|
|
{
|
|
_index -= i;
|
|
return *this;
|
|
}
|
|
value_type& operator[](difference_type i)
|
|
{
|
|
return _accessor[_index + i];
|
|
}
|
|
accessor_iterator<T>& operator++()
|
|
{
|
|
++_index;
|
|
return *this;
|
|
}
|
|
accessor_iterator<T>& operator--()
|
|
{
|
|
--_index;
|
|
return *this;
|
|
}
|
|
accessor_iterator<T>& operator++(int)
|
|
{
|
|
accessor_iterator<T> tmp(*this);
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
accessor_iterator<T>& operator--(int)
|
|
{
|
|
accessor_iterator<T> tmp(*this);
|
|
--*this;
|
|
return tmp;
|
|
}
|
|
value_type& operator*() const
|
|
{
|
|
return _accessor[_index];
|
|
}
|
|
pointer operator->() const
|
|
{
|
|
return &**this;
|
|
}
|
|
void swap(accessor_iterator<T>& other)
|
|
{
|
|
std::swap(_index, other._index);
|
|
std::swap(_accessor, other._accessor);
|
|
}
|
|
private:
|
|
accessor<T> _accessor;
|
|
unsigned int _index;
|
|
|
|
template <typename U>
|
|
friend bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return lhs._index == rhs._index;
|
|
}
|
|
|
|
template <typename U>
|
|
friend typename accessor_iterator<U>::difference_type
|
|
operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return lhs._index - rhs._index;
|
|
}
|
|
|
|
template <typename U>
|
|
friend
|
|
accessor_iterator<U> operator+(accessor_iterator<U> lhs
|
|
, typename accessor_iterator<U>::difference_type rhs)
|
|
{
|
|
lhs._index += rhs;
|
|
return lhs;
|
|
}
|
|
|
|
template <typename U>
|
|
friend
|
|
accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
|
|
, accessor_iterator<U> rhs)
|
|
{
|
|
return rhs + lhs;
|
|
}
|
|
|
|
template <typename U>
|
|
friend bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return lhs._index < rhs._index;
|
|
}
|
|
|
|
template <typename U>
|
|
friend bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return lhs._index <= rhs._index;
|
|
}
|
|
};
|
|
|
|
template <typename U>
|
|
bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return !(lhs < rhs);
|
|
}
|
|
|
|
template <typename U>
|
|
bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return !(lhs <= rhs);
|
|
}
|
|
|
|
template <typename U>
|
|
bool operator!=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
template <typename U>
|
|
void swap(accessor_iterator<U>& lhs, accessor_iterator<U>& rhs)
|
|
{
|
|
lhs.swap(rhs);
|
|
}
|
|
|
|
} }
|
|
|
|
#endif
|