efl/src/bindings/eina_cxx/eina_accessor.hh

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