eina: add a C++ bindings to Eina @feature.

The goal of this library is to make the life of C++ developers easier
when having to manipulate Eina datatype by providing a layer to abstract
those data type in C++. Check examples for now. Documentation will come
soon, but we are pushing that rather sooner to get feedback on those bindings.

As you will notice, this library is just composed of headers. There is no .so
and we do think it is better this way. Reducing ABI and API stability issue for
applications developers who are the primary target of this binding.

Also please note that you will need to have C++11 to use this binding.

Signed-off-by: Cedric Bail <cedric.bail@free.fr>
efl-1.10
Felipe Magno de Almeida 9 years ago committed by Cedric Bail
parent d63507446f
commit f279225a63
  1. 1
      Makefile.am
  2. 18
      configure.ac
  3. 133
      m4/ax_cxx_compile_stdcxx_11.m4
  4. 1
      pc/.gitignore
  5. 12
      pc/eina-cxx.pc.in
  6. 3
      src/Makefile.am
  7. 61
      src/Makefile_Eina_Cxx.am
  8. 45
      src/examples/eina_cxx/Makefile.am
  9. 55
      src/examples/eina_cxx/eina_cxx_list_01.cc
  10. 32
      src/examples/eina_cxx/eina_cxx_thread_01.cc
  11. 44
      src/lib/eina_cxx/Eina.hh
  12. 214
      src/lib/eina_cxx/eina_accessor.hh
  13. 69
      src/lib/eina_cxx/eina_clone_allocators.hh
  14. 105
      src/lib/eina_cxx/eina_error.hh
  15. 544
      src/lib/eina_cxx/eina_inarray.hh
  16. 464
      src/lib/eina_cxx/eina_inlist.hh
  17. 101
      src/lib/eina_cxx/eina_iterator.hh
  18. 28
      src/lib/eina_cxx/eina_lists_auxiliary.hh
  19. 486
      src/lib/eina_cxx/eina_ptrarray.hh
  20. 495
      src/lib/eina_cxx/eina_ptrlist.hh
  21. 26
      src/lib/eina_cxx/eina_ref.hh
  22. 205
      src/lib/eina_cxx/eina_stringshare.hh
  23. 356
      src/lib/eina_cxx/eina_thread.hh
  24. 51
      src/lib/eina_cxx/eina_type_traits.hh
  25. 371
      src/lib/eina_cxx/eina_value.hh
  26. 125
      src/tests/eina_cxx/eina_cxx_suite.cc
  27. 102
      src/tests/eina_cxx/eina_cxx_test_accessor.cc
  28. 191
      src/tests/eina_cxx/eina_cxx_test_eina_value.cc
  29. 72
      src/tests/eina_cxx/eina_cxx_test_error.cc
  30. 388
      src/tests/eina_cxx/eina_cxx_test_inarray.cc
  31. 212
      src/tests/eina_cxx/eina_cxx_test_inlist.cc
  32. 34
      src/tests/eina_cxx/eina_cxx_test_iterator.cc
  33. 180
      src/tests/eina_cxx/eina_cxx_test_ptrarray.cc
  34. 212
      src/tests/eina_cxx/eina_cxx_test_ptrlist.cc
  35. 32
      src/tests/eina_cxx/eina_cxx_test_stringshare.cc
  36. 127
      src/tests/eina_cxx/eina_cxx_test_thread.cc

@ -119,6 +119,7 @@ endif
pkgconfig_DATA += \
pc/eina.pc \
pc/eina-cxx.pc \
pc/eo.pc \
pc/eet.pc \
pc/evas.pc \

@ -890,6 +890,21 @@ EFL_LIB_END([Eina])
#### End of Eina
#### Eina CXX
EFL_LIB_START([Eina_Cxx])
AX_CXX_COMPILE_STDCXX_11([ext])
if test "x${HAVE_CXX11}" -a "x1"; then
have_cxx11="yes"
else
have_cxx11="no"
fi
AM_CONDITIONAL([HAVE_CXX11], [test "x${have_cxx11}" -a "xyes"])
EFL_LIB_END([Eina_Cxx])
#### End of Eina CXX
#### Eet
EFL_LIB_START([Eet])
@ -3927,6 +3942,7 @@ src/Makefile
src/benchmarks/eina/Makefile
src/benchmarks/eo/Makefile
src/examples/eina/Makefile
src/examples/eina_cxx/Makefile
src/examples/eet/Makefile
src/examples/eo/Makefile
src/examples/evas/Makefile
@ -3945,6 +3961,7 @@ spec/efl.spec
pc/evil.pc
pc/escape.pc
pc/eina.pc
pc/eina-cxx.pc
pc/eet.pc
pc/eo.pc
pc/evas-fb.pc
@ -4075,6 +4092,7 @@ echo " Threads.......: ${efl_have_threads} (${features_thread})"
echo " Cryptography..: ${build_crypto}"
echo " X11...........: ${with_x11}"
echo " OpenGL........: ${with_opengl}"
echo " C++11.........: ${have_cxx11}"
echo "Evas............: yes (${features_evas})"
echo " Engines.......: ${features_evas_engine}"
echo " Image Loaders.: ${features_evas_loader}"

@ -0,0 +1,133 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

1
pc/.gitignore vendored

@ -24,6 +24,7 @@
/efreet-trash.pc
/efreet.pc
/eina.pc
/eina-cxx.pc
/eio.pc
/eldbus.pc
/embryo.pc

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Eina C++
Description: A C++ binding for the Eina library
Requires.private: @requirements_pc_eina@
Version: @VERSION@
Libs: -L${libdir} -leina @requirements_public_libs_eina@
Libs.private: @requirements_libs_eina@
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-@VMAJ@/eina -I${includedir}/eina_cxx-@VMAJ@ -I${includedir}/eina_cxx-@VMAJ@/eina_cxx

@ -56,6 +56,8 @@ include Makefile_Emotion.am
include Makefile_Ethumb.am
include Makefile_Ethumb_Client.am
include Makefile_Eina_Cxx.am
.PHONY: benchmark examples
BENCHMARK_SUBDIRS = \
@ -71,6 +73,7 @@ benchmark: all-am
EXAMPLES_SUBDIRS = \
examples/eina \
examples/eina_cxx \
examples/eo \
examples/eet \
examples/evas \

@ -0,0 +1,61 @@
### Library
#lib_LTLIBRARIES += lib/eina/libeina.la
installed_einacxxmainheadersdir = $(includedir)/eina_cxx-@VMAJ@
dist_installed_einacxxmainheaders_DATA = \
lib/eina_cxx/Eina.hh
installed_einacxxheadersdir = $(includedir)/eina_cxx-@VMAJ@/eina_cxx
dist_installed_einacxxheaders_DATA = \
lib/eina_cxx/eina_accessor.hh \
lib/eina_cxx/eina_clone_allocators.hh \
lib/eina_cxx/eina_error.hh \
lib/eina_cxx/eina_inarray.hh \
lib/eina_cxx/eina_inlist.hh \
lib/eina_cxx/eina_iterator.hh \
lib/eina_cxx/eina_lists_auxiliary.hh \
lib/eina_cxx/eina_ptrarray.hh \
lib/eina_cxx/eina_ptrlist.hh \
lib/eina_cxx/eina_ref.hh \
lib/eina_cxx/eina_stringshare.hh \
lib/eina_cxx/eina_thread.hh \
lib/eina_cxx/eina_type_traits.hh \
lib/eina_cxx/eina_value.hh
### Unit tests
if EFL_ENABLE_TESTS
if HAVE_CXX11
check_PROGRAMS += tests/eina_cxx/eina_cxx_suite
TESTS += tests/eina_cxx/eina_cxx_suite
tests_eina_cxx_eina_cxx_suite_SOURCES = \
tests/eina_cxx/eina_cxx_suite.cc \
tests/eina_cxx/eina_cxx_test_inlist.cc \
tests/eina_cxx/eina_cxx_test_inarray.cc \
tests/eina_cxx/eina_cxx_test_iterator.cc \
tests/eina_cxx/eina_cxx_test_ptrarray.cc \
tests/eina_cxx/eina_cxx_test_ptrlist.cc \
tests/eina_cxx/eina_cxx_test_stringshare.cc \
tests/eina_cxx/eina_cxx_test_error.cc \
tests/eina_cxx/eina_cxx_test_accessor.cc \
tests/eina_cxx/eina_cxx_test_thread.cc \
tests/eina_cxx/eina_cxx_test_eina_value.cc
tests_eina_cxx_eina_cxx_suite_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/eina_cxx \
-DTESTS_WD=\"`pwd`\" \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eina_cxx\" \
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/src/tests/eina_cxx\" \
-DTESTS_BUILD_DIR=PACKAGE_BUILD_DIR \
@CHECK_CFLAGS@ \
@EINA_CFLAGS@
tests_eina_cxx_eina_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EINA_LIBS@
tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
endif
endif

@ -0,0 +1,45 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I$(top_builddir)/src/lib/efl \
-I. \
-I$(top_srcdir)/src/lib/eina \
-I$(top_builddir)/src/lib/eina \
-I$(top_srcdir)/src/lib/eina_cxx \
-I$(top_builddir)/src/lib/eina_cxx
LDADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LDFLAGS@ @USE_BOOST_SYSTEM_LIBS@ @USE_BOOST_SYSTEM_LDFLAGS@
AM_CXXFLAGS = @USE_BOOST_CPPFLAGS@
SRCS = \
eina_cxx_list_01.cc
EXTRA_PROGRAMS = \
eina_cxx_list_01 \
eina_cxx_thread_01
eina_cxx_list_01_SOURCES = \
eina_cxx_list_01.cc
eina_cxx_thread_01_SOURCES = \
eina_cxx_thread_01.cc
EXTRA_DIST = $(DATA_FILES)
examples: $(EXTRA_PROGRAMS)
clean-local:
rm -f $(EXTRA_PROGRAMS)
install-examples:
mkdir -p $(datadir)/eina/examples
$(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eina/examples
uninstall-local:
for f in $(SRCS) $(DATA_FILES); do \
rm -f $(datadir)/eina/examples/$$f ; \
done
if ALWAYS_BUILD_EXAMPLES
noinst_PROGRAMS = $(EXTRA_PROGRAMS)
endif

@ -0,0 +1,55 @@
//Compile with:
//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
#include <stdio.h>
#include <Eina.hh>
#include <iterator>
#include <algorithm>
#include <iostream>
template <typename I>
I next(I i, std::size_t n = 1u)
{
for(;n;--n)
++i;
}
int main(int argc, char **argv)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<std::string, efl::eina::heap_copy_allocator> list;
list.push_back("tigh");
list.push_back("adar");
list.push_back("baltar");
list.push_back("roslin");
for(efl::eina::ptr_list<std::string>::const_iterator
first = list.begin(), last = list.end()
;first != last; ++first)
std::cout << *first << std::endl;
efl::eina::ptr_list<std::string>::iterator
iterator = ::next(list.begin(), 2u);
list.insert(iterator, "cain");
iterator = std::find(list.begin(), list.end(), "cain");
assert(iterator != list.end() && ::next(iterator) != list.end());
list.insert(::next(iterator), "zarek");
list.insert(list.begin(), "adama");
iterator = std::find(list.begin(), list.end(), "cain");
assert(iterator != list.end());
list.insert(iterator, "gaeta");
list.insert(::next(list.begin()), "lampkin");
for(efl::eina::ptr_list<std::string>::const_iterator
first = list.begin(), last = list.end()
;first != last; ++first)
std::cout << *first << std::endl;
}

@ -0,0 +1,32 @@
//Compile with:
//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
#include <stdio.h>
#include <Eina.hh>
#include <iterator>
#include <algorithm>
#include <iostream>
namespace eina = efl::eina;
void thread1(eina::mutex& m)
{
}
int main(int argc, char **argv)
{
eina::eina_init eina_init;
eina::eina_threads_init threads_init;
eina::mutex m;
eina::condition_variable c;
eina::unique_lock<eina::mutex> l(m);
eina::thread thread1(&::thread1, eina::ref(m));
thread1.join();
}

@ -0,0 +1,44 @@
#ifndef EINA_HH_
#define EINA_HH_
#include <eina_iterator.hh>
#include <eina_ptrarray.hh>
#include <eina_ptrlist.hh>
#include <eina_inarray.hh>
#include <eina_inlist.hh>
#include <eina_stringshare.hh>
#include <eina_error.hh>
#include <eina_accessor.hh>
#include <eina_thread.hh>
#include <eina_value.hh>
#include <eina_ref.hh>
namespace efl { namespace eina {
struct eina_init
{
eina_init()
{
::eina_init();
}
~eina_init()
{
::eina_shutdown();
}
};
struct eina_threads_init
{
eina_threads_init()
{
::eina_threads_init();
}
~eina_threads_init()
{
::eina_threads_shutdown();
}
};
} }
#endif

@ -0,0 +1,214 @@
#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

@ -0,0 +1,69 @@
#ifndef EINA_CLONE_ALLOCATORS_HH_
#define EINA_CLONE_ALLOCATORS_HH_
#include <memory>
namespace efl { namespace eina {
struct heap_copy_allocator
{
template <typename T>
static T* allocate_clone(T const& v)
{
return new T(v);
}
template <typename T>
static void deallocate_clone(T* p)
{
#ifdef EFL_EINA_CXX11
std::default_delete<T>()(p);
#else
delete p;
#endif
}
};
struct heap_clone_allocator
{
template <typename T>
static T* allocate_clone(T const& v)
{
return new_clone(v);
}
template <typename T>
static void deallocate_clone(T* p)
{
delete_clone(p);
}
};
struct view_clone_allocator
{
template <typename T>
static T* allocate_clone(T const& v)
{
return const_cast<T*>(&v);
}
template <typename T>
static void deallocate_clone(T* p)
{
}
};
struct heap_no_copy_allocator
{
template <typename T>
static void deallocate_clone(T* p)
{
#ifdef EFL_EINA_CXX11
std::default_delete<T>()(p);
#else
delete p;
#endif
}
};
} }
#endif

@ -0,0 +1,105 @@
#ifndef _EINA_ERROR_HH
#define _EINA_ERROR_HH
#include <Eina.h>
#include <system_error>
namespace efl { namespace eina {
using std::errc;
using std::system_error;
using std::error_code;
using std::error_condition;
typedef std::error_category system_error_category;
inline system_error_category const& get_generic_category()
{
return ::std::generic_category();
}
inline system_error_category const& get_system_category()
{
return ::std::system_category();
}
enum error_type {};
struct error_category : system_error_category
{
const char* name() const throw()
{
return "eina";
}
bool equivalent(int code, eina::error_condition const& condition) const throw()
{
return code == condition.value();
}
bool equivalent(eina::error_code const& code, int condition) const throw()
{
return code.value() == condition;
}
std::string message(int condition) const
{
const char* e = ::eina_error_msg_get(condition);
return e? e : "::eina_error_msg_get returned NULL. No error message available";
}
};
inline eina::system_error_category& eina_error_category()
{
static error_category _error_category;
return _error_category;
}
inline eina::error_code get_error_code()
{
Eina_Error error = eina_error_get();
if(error)
{
eina_error_set(0);
return eina::error_code(error, eina_error_category());
}
else
return eina::error_code();
}
inline eina::error_condition get_error_condition()
{
Eina_Error error = eina_error_get();
if(error)
{
eina_error_set(0);
return eina::error_condition(error, eina_error_category());
}
else
return eina::error_condition();
}
inline error_type get_error_code_enum()
{
return static_cast<error_type>( ::eina_error_get() );
}
inline void throw_on_error()
{
eina::error_code ec = get_error_code();
if(ec)
{
throw eina::system_error(ec, "EFL Eina Error");
}
}
} }
namespace std {
template <> struct is_error_condition_enum< ::efl::eina::error_type> : true_type {};
template <> struct is_error_code_enum< ::efl::eina::error_type> : true_type {};
}
#endif

@ -0,0 +1,544 @@
#ifndef EINA_INARRAY_HH_
#define EINA_INARRAY_HH_
#include <Eina.h>
#include <eina_type_traits.hh>
#include <iterator>
#include <cstring>
#include <cassert>
namespace efl { namespace eina {
struct _inarray_common_base
{
typedef std::size_t size_type;
explicit _inarray_common_base(size_type member_size)
: _array( ::eina_inarray_new(member_size, 0) )
{
}
~_inarray_common_base()
{
::eina_inarray_free(_array);
}
size_type size() const
{
return ::eina_inarray_count(_array);
}
bool empty() const
{
return size() == 0u;
}
Eina_Inarray* _array;
private:
_inarray_common_base(_inarray_common_base const& other);
_inarray_common_base& operator=(_inarray_common_base const& other);
};
template <typename T>
class _pod_inarray : _inarray_common_base
{
typedef _inarray_common_base _base_type;
public:
typedef T value_type;
typedef T& reference;
typedef T const& const_reference;
typedef T* pointer;
typedef T const* const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
using _base_type::size;
using _base_type::empty;
_pod_inarray() : _base_type(sizeof(T))
{
}
_pod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
{
while(n--)
push_back(t);
}
template <typename InputIterator>
_pod_inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(sizeof(T))
{
while(i != j)
{
push_back(*i);
++i;
}
}
_pod_inarray(_pod_inarray<T>const& other)
: _base_type(sizeof(T))
{
insert(end(), other.begin(), other.end());
}
~_pod_inarray()
{
}
_pod_inarray<T>& operator=(_pod_inarray<T>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
void clear()
{
::eina_inarray_flush(_array);
}
void push_back(T const& value)
{
eina_inarray_push(_array, &value);
}
void pop_back()
{
eina_inarray_pop(_array);
}
iterator insert(iterator i, value_type const& t)
{
if(i != end())
{
T* q = static_cast<iterator>
( ::eina_inarray_alloc_at(_array, i - begin(), 1u));
std::memcpy(q, &t, sizeof(t));
return q;
}
else
{
push_back(t);
return end()-1;
}
}
iterator insert(iterator i, size_t n, value_type const& t)
{
T* q;
if(i != end())
{
q = static_cast<iterator>
( ::eina_inarray_alloc_at(_array, i - &_array->members, n));
}
else
{
q = eina_inarray_grow(_array, n);
}
for(T* p = q; n; --n, ++p)
std::memcpy(p, &t, sizeof(t));
return q;
}
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
size_type n = 0;
while(i != j)
{
p = insert(p, *i);
++p;
++i;
++n;
}
return p - n;
}
iterator erase(iterator q)
{
::eina_inarray_remove_at(_array, q - begin());
return q;
}
iterator erase(iterator i, iterator j)
{
while(i != j)
{
erase(--j);
}
return i;
}
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
void assign(size_type n, value_type const& t);
value_type& back()
{
assert(!empty());
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
}
value_type const& back() const
{
return const_cast<_pod_inarray<T>&>(*this).back();
}
value_type& front()
{
assert(!empty());
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
}
value_type const& front() const
{
return const_cast<_pod_inarray<T>&>(*this).front();
}
iterator begin()
{
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, 0u));
}
iterator end()
{
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, size()-1)) + 1;
}
const_iterator begin() const
{
return const_cast< _pod_inarray<T>&>(*this).begin();
}
const_iterator end() const
{
return const_cast< _pod_inarray<T>&>(*this).end();
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(end());
}
reverse_iterator rbegin()
{
return reverse_iterator(begin());
}
reverse_iterator rend()
{
return reverse_iterator(end());
}
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();
}
void swap(_pod_inarray<T>& other)
{
std::swap(_array, other._array);
}
size_type max_size() const { return -1; }
Eina_Inarray* native_handle()
{
return this->_array;
}
Eina_Inarray const* native_handle() const
{
return this->_array;
}
};
template <typename T>
class _nonpod_inarray : _inarray_common_base
{
typedef _inarray_common_base _base_type;
public:
typedef T value_type;
typedef T& reference;
typedef T const& const_reference;
typedef T* pointer;
typedef T const* const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
using _base_type::size;
using _base_type::empty;
_nonpod_inarray() : _base_type(sizeof(T))
{
}
_nonpod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
{
while(n--)
push_back(t);
}
template <typename InputIterator>
_nonpod_inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(sizeof(T))
{
while(i != j)
{
push_back(*i);
++i;
}
}
_nonpod_inarray(_nonpod_inarray<T>const& other)
: _base_type(sizeof(T))
{
insert(end(), other.begin(), other.end());
}
~_nonpod_inarray()
{
for(T* first = static_cast<T*>(_array->members)
, *last = first + _array->len; first != last; ++first)
first->~T();
}
_nonpod_inarray<T>& operator=(_nonpod_inarray<T>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
void clear()
{
for(T* first = static_cast<T*>(_array->members)
, *last = first + _array->len; first != last; ++first)
first->~T();
::eina_inarray_flush(_array);
}
void push_back(T const& value)
{
insert(end(), 1u, value);
}
void pop_back()
{
T* elem = static_cast<T*>(_array->members) + _array->len - 1;
elem->~T();
eina_inarray_pop(_array);
}
iterator insert(iterator i, value_type const& t)
{
return insert(i, 1u, t);
}
iterator insert(iterator i, size_t n, value_type const& t)
{
if(_array->max - _array->len >= n)
{
iterator end = static_cast<T*>(_array->members)
+ _array->len
, last = end + n;
_array->len += n;
std::reverse_iterator<iterator>
dest(last), src(end), src_end(i);
for(;src != src_end; ++src)
{
if(dest.base() <= end)
*dest++ = *src;
else
new (&*dest++) T(*src);
}
iterator j = i;
for(size_type i = 0;i != n;++i)
{
if(j < end)
*j = t;
else
new (&*j++) T(t);
}
}
else
{
size_type index = i - static_cast<iterator>(_array->members);
Eina_Inarray* old_array = eina_inarray_new(_array->member_size, 0);
*old_array = *_array;
_array->len = _array->max = 0;
_array->members = 0;
eina_inarray_resize(_array, old_array->len+n);
_array->len = old_array->len+n;
iterator old_first = static_cast<iterator>(old_array->members)
, first = begin()
, last = first + _array->len;
i = index + begin();
while(first != i)
{
new (&*first++) T(*old_first);
old_first++->~T();
}
for(size_type i = 0;i != n;++i)
new (&*first++) T(t);
assert(last - first == _array->len - index - n);
while(first != last)
{
new (&*first++) T(*old_first);
old_first++->~T();
}
}
return i;
}
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
size_type n = 0;
while(i != j)
{
p = insert(p, *i);
++p;
++i;
++n;
}
return p - n;
}
iterator erase(iterator q)
{
return erase(q, q+1);
}
iterator erase(iterator i, iterator j)
{
iterator last = end();
iterator k = i, l = j;
while(l != last)
*k++ = *l++;
while(k != last)
k++->~T();
_array->len -= j - i;
return i;
}
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
void assign(size_type n, value_type const& t);
value_type& back()
{
assert(!empty());
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
}
value_type const& back() const
{
return const_cast<_nonpod_inarray<T>&>(*this).back();
}
value_type& front()
{
assert(!empty());
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
}
value_type const& front() const
{
return const_cast<_nonpod_inarray<T>&>(*this).front();
}
iterator begin()
{
return static_cast<iterator>(_array->members);
}
iterator end()
{
return static_cast<iterator>(_array->members) + _array->len;
}
const_iterator begin() const
{
return const_cast< _nonpod_inarray<T>&>(*this).begin();
}
const_iterator end() const
{
return const_cast< _nonpod_inarray<T>&>(*this).end();
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_reverse_iterator(end());
}
reverse_iterator rbegin()
{
return reverse_iterator(begin());
}
reverse_iterator rend()
{
return reverse_iterator(end());
}
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();
}
void swap(_nonpod_inarray<T>& other)
{
std::swap(_array, other._array);
}
size_type max_size() const { return -1; }
Eina_Inarray* native_handle()
{
return this->_array;
}
Eina_Inarray const* native_handle() const
{
return this->_array;
}
};
template <typename T>
class inarray : public eina::if_<eina::is_pod<T>, _pod_inarray<T>
, _nonpod_inarray<T> >::type
{
typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T>
, _nonpod_inarray<T> >::type _base_type;
public:
inarray() : _base_type() {}
inarray(typename _base_type::size_type n, typename _base_type::value_type const& t)
: _base_type(n, t) {}
template <typename InputIterator>
inarray(InputIterator i, InputIterator const& j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(i, j)
{}
};
template <typename T>
bool operator==(inarray<T> const& lhs, inarray<T> const& rhs)
{
return lhs.size() == rhs.size() &&
std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename T>
bool operator!=(inarray<T> const& lhs, inarray<T> const& rhs)
{
return !(lhs == rhs);
}
template <typename T>
void swap(inarray<T>& lhs, inarray<T>& rhs)
{
lhs.swap(rhs);
}
} }
#endif