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>
This commit is contained in:
Felipe Magno de Almeida 2014-02-25 17:24:32 -03:00 committed by Cedric Bail
parent d63507446f
commit f279225a63
36 changed files with 5595 additions and 0 deletions

View File

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

View File

@ -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}"

View File

@ -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
View File

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

12
pc/eina-cxx.pc.in Normal file
View File

@ -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

View File

@ -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 \

61
src/Makefile_Eina_Cxx.am Normal file
View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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();
}

44
src/lib/eina_cxx/Eina.hh Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,464 @@
#ifndef EINA_INLIST_HH_
#define EINA_INLIST_HH_
#include <Eina.h>
#include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh>
#include <eina_accessor.hh>
#include <iterator>
namespace efl { namespace eina {
template <typename T>
struct _inlist_node
{
EINA_INLIST;
T object;
};
template <typename T>
_inlist_node<T>* _get_node(Eina_Inlist* l)
{
return static_cast<_inlist_node<T>*>(static_cast<void*>(l));
}
template <typename T>
_inlist_node<T> const* _get_node(Eina_Inlist const* l)
{
return const_cast<Eina_Inlist*>(l);
}
template <typename T>
Eina_Inlist* _get_list(_inlist_node<T>* n)
{
if(n)
return EINA_INLIST_GET(n);
else
return 0;
}
template <typename T>
Eina_Inlist const* _get_list(_inlist_node<T> const* n)
{
return _get_list(const_cast<_inlist_node<T>*>(n));
}
template <typename T>
struct _inlist_iterator
{
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
_inlist_iterator() {}
explicit _inlist_iterator(_inlist_node<T>* list, _inlist_node<T>* node)
: _list(list), _node(node) {}
_inlist_iterator<T>& operator++()
{
_node = _get_node<T>(_node->__in_list.next);
return *this;
}
_inlist_iterator<T> operator++(int)
{
_inlist_iterator<T> tmp(*this);
++*this;
return tmp;
}
_inlist_iterator<T>& operator--()
{
if(_node)
_node = _get_node<T>(_node->__in_list.prev);
else
_node = _get_node<T>(_list->__in_list.last);
return *this;
}
_inlist_iterator<T> operator--(int)
{
_inlist_iterator<T> tmp(*this);
--*this;
return tmp;
}
T const& operator*() const
{
return _node->object;
}
T const* operator->() const
{
return &_node->object;
}
_inlist_node<T>* native_handle()
{
return _node;
}
_inlist_node<T> const* native_handle() const
{
return _node;
}
private:
_inlist_node<T>* _list;
_inlist_node<T>* _node;
friend bool operator==(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
{
return lhs._node == rhs._node;
}
};
template <typename T>
bool operator!=(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
{
return !(lhs == rhs);
}
template <typename T, typename Allocator>
struct _inlist_common_base
{
typedef typename Allocator::template rebind<_inlist_node<T> >::other node_allocator_type;
typedef Allocator allocator_type;
typedef _inlist_node<T> node_type;
_inlist_common_base(Allocator allocator)
: _impl(allocator) {}
_inlist_common_base()
{}
~_inlist_common_base()
{
clear();
}
void clear()
{
Eina_Inlist* p = _impl._list;
Eina_Inlist* q;
while(p)
{
q = p->next;
_inlist_node<T>* node = _get_node<T>(p);
node->~_inlist_node<T>();
get_node_allocator().deallocate(node, 1);
p = q;
}
_impl._list = 0;
}
node_allocator_type& get_node_allocator()
{
return _impl;
}
// For EBO
struct _inlist_impl : node_allocator_type
{
_inlist_impl(Allocator allocator)
: node_allocator_type(allocator), _list(0)
{}
_inlist_impl() : _list(0) {}
Eina_Inlist* _list;
};
_inlist_impl _impl;
private:
_inlist_common_base(_inlist_common_base const& other);
_inlist_common_base& operator=(_inlist_common_base const& other);
};
template <typename T, typename Allocator = std::allocator<T> >
class inlist : protected _inlist_common_base<T, Allocator>
{
typedef _inlist_common_base<T, Allocator> _base_type;
typedef typename _base_type::node_type _node_type;
public:
typedef typename _base_type::allocator_type allocator_type;
typedef typename allocator_type::value_type value_type;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef _inlist_iterator<T const> const_iterator;
typedef _inlist_iterator<T> iterator;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
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::clear;
inlist() {}
inlist(size_type n, value_type const& t)
{
while(n--)
push_back(t);
}
template <typename InputIterator>
inlist(InputIterator i, InputIterator const& j
, allocator_type const& alloc = allocator_type()
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(alloc)
{
while(i != j)
{
push_back(*i);
++i;
}
}
inlist(inlist<T, Allocator>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
inlist<T, Allocator>& operator=(inlist<T, Allocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
size_type size() const
{
return ::eina_inlist_count(this->_impl._list);
}
bool empty() const
{
return this->_impl._list == 0;
}
allocator_type get_allocator() const
{
return allocator_type(this->get_node_allocator());
}
void push_back(T const& value)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
try
{
new (&node->object) T(value);
// eina_inlist_append can't fail
this->_impl._list = eina_inlist_append(this->_impl._list, _get_list(node));
}
catch(...)
{
this->get_node_allocator().deallocate(node, 1);
throw;
}
}
void push_front(T const& value)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
try
{
new (&node->object) T(value);
// eina_inlist_prepend can't fail
this->_impl._list = eina_inlist_prepend(this->_impl._list, _get_list(node));
}
catch(...)
{
this->get_node_allocator().deallocate(node, 1);
throw;
}
}
void pop_back()
{
this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list->last);
}
void pop_front()
{
this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list);
}
iterator insert(iterator i, value_type const& t)
{
_node_type* node ( this->get_node_allocator().allocate(1) );
try
{
new (&node->object) T(t);
// eina_inlist_prepend_relative can't fail
this->_impl._list = _eina_inlist_prepend_relative
(this->_impl._list, _get_list(node)
, _get_list(i.native_handle()));
return iterator(_get_node<T>(this->_impl._list), node);
}
catch(...)
{
this->get_node_allocator().deallocate(node, 1);
throw;
}
}
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
if(n--)
r = insert(i, t);
while(n--)
insert(i, t);
return r;
}
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
iterator r = p;
if(i != j)
{
value_type v = *i;
r = insert(p, v);
++i;
}
while(i != j)
{
insert(p, *i);
++i;
}
return r;
}
iterator erase(iterator q)
{
if(q.native_handle())
{
iterator r(_get_node<T>(this->_impl._list), _get_node<T>(_get_list(q.native_handle())->next));
this->_impl._list = eina_inlist_remove(this->_impl._list, _get_list(q.native_handle()));
return r;
}
else
return q;
}
iterator erase(iterator i, iterator j)
{
while(i != j)
i = erase(i);
if(j.native_handle())
return j;
else
return end();
}
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
clear();
insert(end(), i, j);
}
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
value_type& back()
{
return _get_node<T>(this->_impl._list->last)->object;
}
value_type const& back() const
{
return const_cast<inlist<T, Allocator>&>(*this).back();
}
value_type& front()
{
return _get_node<T>(this->_impl._list)->object;
}
value_type const& front() const
{
return const_cast<inlist<T, Allocator>&>(*this).front();
}
const_iterator begin() const
{
return const_iterator(_get_node<T const>(this->_impl._list), _get_node<T const>(this->_impl._list));
}
const_iterator end() const
{
return const_iterator(_get_node<T const>(this->_impl._list), 0);
}
iterator begin()
{
return iterator(_get_node<T>(this->_impl._list), _get_node<T>(this->_impl._list));
}
iterator end()
{
return iterator(_get_node<T>(this->_impl._list), 0);
}
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(inlist<T, Allocator>& other)
{
std::swap(this->_impl._list, other._impl._list);
}
size_type max_size() const { return -1; }
Eina_Inlist* native_handle()
{
return this->_impl._list;
}
Eina_Inlist const* native_handle() const
{
return this->_impl._list;
}
eina::accessor<T const> accessor() const
{
return eina::accessor<T const>(eina_inlist_accessor_new(this->_impl._list));
}
eina::accessor<T> accessor()
{
return eina::accessor<T>(eina_inlist_accessor_new(this->_impl._list));
}
};
template <typename T, typename Allocator1, typename Allocator2>
bool operator==(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
{
return lhs.size() == rhs.size() &&
std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename T, typename Allocator1, typename Allocator2>
bool operator!=(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
{
return !(lhs == rhs);
}
template <typename T, typename Allocator>
void swap(inlist<T, Allocator>& lhs, inlist<T, Allocator>& rhs)
{
lhs.swap(rhs);
}
} }
#endif

View File

@ -0,0 +1,101 @@
#ifndef EINA_ITERATOR_HH_
#define EINA_ITERATOR_HH_
#include <Eina.h>
#include <cstdlib>
#include <iterator>
namespace efl { namespace eina {
template <typename T>
struct _common_iterator_base
{
private:
typedef _common_iterator_base<T> self_type;
public:
typedef T const value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
_common_iterator_base() {}
explicit _common_iterator_base(Eina_Iterator* iterator)
: _iterator(iterator) {}
~_common_iterator_base()
{
if(_iterator)
eina_iterator_free(_iterator);
}
_common_iterator_base(self_type const& other)
: _iterator(other._iterator)
{
other._iterator = 0;
}
_common_iterator_base& operator=(self_type const& other)
{
_iterator = other._iterator;
other._iterator = 0;
return *this;
}
protected:
mutable Eina_Iterator* _iterator;
friend inline bool operator==(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
{
return lhs._iterator == rhs._iterator;
}
friend inline bool operator!=(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
{
return !(lhs == rhs);
}
};
template <typename T>
struct iterator : _common_iterator_base<T const>
{
private:
typedef _common_iterator_base<T const> base_type;
typename base_type::pointer _value;
typedef iterator<T> self_type;
public:
typedef typename base_type::value_type value_type;
typedef typename base_type::pointer pointer;
typedef typename base_type::reference reference;
typedef typename base_type::difference_type difference_type;
typedef typename base_type::iterator_category iterator_category;
explicit iterator(Eina_Iterator* iterator = 0)
: base_type(iterator)
{
if(this->_iterator)
++*this;
}
self_type& operator++()
{
void* data;
Eina_Bool r = ::eina_iterator_next(this->_iterator, &data);
if(!r)
this->_iterator = 0;
_value = static_cast<pointer>(data);
return *this;
}
self_type& operator++(int)
{
return ++**this;
}
value_type& operator*() const
{
return *_value;
}
pointer operator->() const
{
return _value;
}
};
} }
#endif

View File

@ -0,0 +1,28 @@
#ifndef _EINA_LISTS_AUXILIARY_HH
#define _EINA_LISTS_AUXILIARY_HH
#include <Eina.h>
namespace efl { namespace eina {
inline Eina_List* _eina_list_prepend_relative_list(Eina_List* list, const void* data, Eina_List* relative) EINA_ARG_NONNULL(2)
{
if(relative)
return ::eina_list_prepend_relative_list(list, data, relative);
else
return ::eina_list_append(list, data);
}
inline Eina_Inlist *_eina_inlist_prepend_relative(Eina_Inlist *in_list,
Eina_Inlist *in_item,
Eina_Inlist *in_relative) EINA_ARG_NONNULL(2)
{
if(in_relative)
return ::eina_inlist_prepend_relative(in_list, in_item, in_relative);
else
return ::eina_inlist_append(in_list, in_item);
}
} }
#endif

View File

@ -0,0 +1,486 @@
#ifndef EINA_PTRARRAY_HH_
#define EINA_PTRARRAY_HH_
#include <Eina.h>
#include <eina_clone_allocators.hh>
#include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh>
#include <memory>
#include <iterator>
#include <cstdlib>
#include <cassert>
namespace efl { namespace eina {
struct _ptr_array_iterator_base
{
_ptr_array_iterator_base() : _ptr(0) {}
_ptr_array_iterator_base(void** ptr)
: _ptr(ptr)
{}
void** _ptr;
};
template <typename T>
struct _ptr_array_iterator : protected _ptr_array_iterator_base
{
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
_ptr_array_iterator() {}
explicit _ptr_array_iterator(void** ptr)
: _ptr_array_iterator_base(ptr)
{
}
_ptr_array_iterator(_ptr_array_iterator<typename remove_cv<value_type>::type> const& other)
: _ptr_array_iterator_base(static_cast<_ptr_array_iterator_base const&>(other))
{
}
_ptr_array_iterator<T>& operator++()
{
++_ptr;
return *this;
}
_ptr_array_iterator<T> operator++(int)
{
_ptr_array_iterator<T> tmp(*this);
++*this;
return tmp;
}
_ptr_array_iterator<T>& operator--()
{
--_ptr;
return *this;
}
_ptr_array_iterator<T> operator--(int)
{
_ptr_array_iterator<T> tmp(*this);
--*this;
return tmp;
}
reference operator*() const
{
return *static_cast<pointer>(*_ptr);
}
pointer operator->() const
{
return &**this;
}
void** native_handle() const
{
return _ptr;
}
friend inline bool operator==(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs)
{
return lhs._ptr == rhs._ptr;
}
friend inline bool operator!=(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs)
{
return !(lhs == rhs);
}
friend inline _ptr_array_iterator<T> operator+(_ptr_array_iterator<T> lhs
, difference_type size)
{
lhs._ptr += size;
return lhs;
}
friend inline _ptr_array_iterator<T> operator-(_ptr_array_iterator<T> lhs
, difference_type size)
{
lhs._ptr -= size;
return lhs;
}
friend inline difference_type operator-(_ptr_array_iterator<T> lhs
, _ptr_array_iterator<T> rhs)
{
return lhs._ptr - rhs._ptr;
}
};
template <typename T, typename CloneAllocator>
struct _ptr_array_common_base
{
typedef CloneAllocator clone_allocator_type;
_ptr_array_common_base(CloneAllocator clone_allocator)
: _impl(clone_allocator)
{}
_ptr_array_common_base(Eina_Array* _array)
: _impl(_array)
{}
_ptr_array_common_base() {}
CloneAllocator& _get_clone_allocator()
{
return _impl;
}
CloneAllocator const& _get_clone_allocator() const
{
return _impl;
}
void _delete_clone(T const* p)
{
_get_clone_allocator().deallocate_clone(p);
}
T* _new_clone(T const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
struct _ptr_array_impl : CloneAllocator
{
_ptr_array_impl() : _array( ::eina_array_new(32u) ) {}
_ptr_array_impl(CloneAllocator allocator)
: clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {}
Eina_Array* _array;
};
_ptr_array_impl _impl;
private:
_ptr_array_common_base(_ptr_array_common_base const& other);
_ptr_array_common_base& operator=(_ptr_array_common_base const& other);
};
template <typename T, typename CloneAllocator = heap_no_copy_allocator>
class ptr_array : protected _ptr_array_common_base<T, CloneAllocator>
{
typedef _ptr_array_common_base<T, CloneAllocator> _base_type;
public:
typedef T value_type;
typedef T& reference;
typedef T const& const_reference;
typedef _ptr_array_iterator<T const> const_iterator;
typedef _ptr_array_iterator<T> iterator;
typedef T* pointer;
typedef T const* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef CloneAllocator clone_allocator_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
ptr_array() {}
ptr_array(size_type n, const_reference t)
{
while(n--)
push_back(t);
}
template <typename InputIterator>
ptr_array(InputIterator i, InputIterator const& j
, clone_allocator_type const& alloc = clone_allocator_type()
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(alloc)
{
while(i != j)
{
push_back(*i);
++i;
}
}
ptr_array(ptr_array<T, CloneAllocator> const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
template <typename CloneAllocator1>
ptr_array(ptr_array<T, CloneAllocator1>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
~ptr_array()
{
clear();
}
ptr_array<T, CloneAllocator>& operator=(ptr_array<T, CloneAllocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
void clear()
{
for(iterator first = begin(), last = end(); first != last; ++first)
this->_delete_clone(&*first);
eina_array_flush(this->_impl._array);
}
std::size_t size() const
{
return eina_array_count(this->_impl._array);
}
bool empty() const
{
return size() == 0u;
}
clone_allocator_type get_clone_allocator() const
{
return clone_allocator_type(this->_get_clone_allocator());
}
void push_back(const_reference a)
{
push_back(this->_new_clone(a));
}
void push_back(pointer p)
{
std::auto_ptr<value_type> p1(p);
push_back(p1);
}
void push_back(std::auto_ptr<T>& p)
{
if(eina_array_push(this->_impl._array, p.get()))
p.release();
else
throw std::bad_alloc();
}
void pop_back()
{
eina_array_pop(this->_impl._array);
}
iterator insert(iterator i, value_type const& t)
{
return insert(i, this->_new_clone(t));
}
iterator insert(iterator i, pointer pv)
{
std::auto_ptr<value_type> p(pv);
return insert(i, p);
}
iterator insert(iterator i, std::auto_ptr<value_type>& p)
{
std::size_t j
= i.native_handle() - this->_impl._array->data
, size = this->size();
if(eina_array_push(this->_impl._array, p.get()))
{
if(size - j)
{
memmove(
this->_impl._array->data + j + 1
, this->_impl._array->data + j
, (size - j)*sizeof(void*));
// PRE: Q:[j, size) = [j+1, size+1)
pointer* data = static_cast<pointer*>
(static_cast<void*>(this->_impl._array->data));
data[j] = p.get();
}
p.release();
return iterator(this->_impl._array->data + j);
}
else
throw std::bad_alloc();
}
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
if(n--)
r = insert(i, t);
while(n--)
insert(i, t);
return r;
}
iterator insert(iterator i, size_t n, pointer p)
{
iterator r = i;
if(n--)
r = insert(i, p);
while(n--)
insert(i, this->_new_clone(p));
return r;
}
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
size_type index = p.native_handle() - this->_impl._array->data;
while(i != j)
{
p = insert(p, this->_new_clone(*i));
++p;
++i;
}
return iterator(this->_impl._array->data + index);
}
iterator erase(iterator q)
{
size_type size = this->size()
, i = q.native_handle() - this->_impl._array->data;
memmove(q.native_handle()
, q.native_handle() + 1
, (size - i - 1)*sizeof(void*));
eina_array_pop(this->_impl._array);
return q;
}
iterator erase(iterator i, iterator j)
{
size_type size = this->size()
, distance = std::distance(i, j);
memmove(i.native_handle()
, j.native_handle()
, (size - distance)*sizeof(void*));
while(distance--)
eina_array_pop(this->_impl._array);
return i;
}
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
clear();
insert(end(), i, j);
}
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
value_type& back()
{
return *static_cast<pointer>(this->_impl._array->data[size()-1]);
}
value_type const& back() const
{
return const_cast<ptr_array<T, CloneAllocator>&>(*this).back();
}
value_type& front()
{
return *static_cast<pointer>(this->_impl._array->data[0]);
}
value_type const& front() const
{
return const_cast<ptr_array<T, CloneAllocator>&>(*this).front();
}
const_reference operator[](size_type index) const
{
pointer data = static_cast<pointer>
(this->_impl._array->data[index]);
return *data;
}
reference operator[](size_type index)
{
return const_cast<reference>
(const_cast<ptr_array<T, CloneAllocator>const&>(*this)[index]);
}
const_iterator begin() const
{
return const_iterator(this->_impl._array->data);
}
const_iterator end() const
{
return const_iterator(this->_impl._array->data + size());
}
iterator begin()
{
return iterator(this->_impl._array->data);
}
iterator end()
{
return iterator(this->_impl._array->data + size());
}
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();
}
eina::iterator<T> ibegin()
{
return eina::iterator<T>( ::eina_array_iterator_new(this->_impl._array) );
}
eina::iterator<T> iend()
{
return eina::iterator<T>();
}
eina::iterator<T const> ibegin() const
{
return eina::iterator<T const>( ::eina_array_iterator_new(this->_impl._array) );
}
eina::iterator<T const> iend() const
{
return eina::iterator<T const>();
}
eina::iterator<T const> cibegin() const
{
return ibegin();
}
eina::iterator<T const> ciend() const
{
return iend();
}
void swap(ptr_array<T, CloneAllocator>& other)
{
std::swap(this->_impl._array, other._impl._array);
}
size_type max_size() const { return -1; }
Eina_Array* native_handle()
{
return this->_impl._array;
}
Eina_Array const* native_handle() const
{
return this->_impl._array;
}
};
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator==(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
{
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator!=(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
{
return !(lhs == rhs);
}
template <typename T, typename CloneAllocator>
void swap(ptr_array<T, CloneAllocator>& lhs, ptr_array<T, CloneAllocator>& rhs)
{
lhs.swap(rhs);
}
} }
#endif

View File

@ -0,0 +1,495 @@
#ifndef EINA_LIST_HH_
#define EINA_LIST_HH_
#include <Eina.h>
#include <eina_clone_allocators.hh>
#include <eina_lists_auxiliary.hh>
#include <eina_type_traits.hh>
#include <eina_accessor.hh>
#include <memory>
#include <iterator>
namespace efl { namespace eina {
struct _ptr_list_iterator_base
{
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
_ptr_list_iterator_base() : _list(0) {}
_ptr_list_iterator_base(Eina_List* list, Eina_List* node)
: _list(list), _node(node)
{}
protected:
Eina_List *_list, *_node;
};
template <typename T>
struct _ptr_list_iterator : _ptr_list_iterator_base
{
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
_ptr_list_iterator() {}
explicit _ptr_list_iterator(Eina_List* list, Eina_List* node)
: _ptr_list_iterator_base(list, node)
{
}
_ptr_list_iterator(_ptr_list_iterator<typename remove_cv<value_type>::type> const& other)
: _ptr_list_iterator_base(static_cast<_ptr_list_iterator_base const&>(other))
{
}
_ptr_list_iterator<T>& operator++()
{
_node = eina_list_next(_node);
return *this;
}
_ptr_list_iterator<T> operator++(int)
{
_ptr_list_iterator<T> tmp(*this);
++*this;
return tmp;
}
_ptr_list_iterator<T>& operator--()
{
if(_node)
_node = eina_list_prev(_node);
else
_node = eina_list_last(_list);
return *this;
}
_ptr_list_iterator<T> operator--(int)
{
_ptr_list_iterator<T> tmp(*this);
--*this;
return tmp;
}
reference operator*() const
{
void* data = eina_list_data_get(_node);
return *static_cast<pointer>(data);
}
pointer operator->() const
{
return &**this;
}
Eina_List* native_handle()
{
return _node;
}
Eina_List const* native_handle() const
{
return _node;
}
friend inline bool operator==(_ptr_list_iterator<T> lhs, _ptr_list_iterator<T> rhs)
{
return lhs._node == rhs._node;
}
friend inline bool operator!=(_ptr_list_iterator<T> lhs, _ptr_list_iterator<T> rhs)
{
return !(lhs == rhs);
}
};
template <typename T, typename CloneAllocator>
struct _ptr_list_common_base
{
typedef CloneAllocator clone_allocator_type;
_ptr_list_common_base(CloneAllocator clone_allocator)
: _impl(clone_allocator)
{}
_ptr_list_common_base(Eina_List* _list)
: _impl(_list)
{}
_ptr_list_common_base() {}
CloneAllocator& _get_clone_allocator()
{
return _impl;
}
CloneAllocator const& _get_clone_allocator() const
{
return _impl;
}
void _delete_clone(T const* p)
{
_get_clone_allocator().deallocate_clone(p);
}
T* _new_clone(T const& a)
{
return _get_clone_allocator().allocate_clone(a);
}
struct _ptr_list_impl : CloneAllocator
{
_ptr_list_impl() : _list(0) {}
_ptr_list_impl(CloneAllocator allocator)
: clone_allocator_type(allocator), _list(0) {}
Eina_List* _list;
};
_ptr_list_impl _impl;
private:
_ptr_list_common_base(_ptr_list_common_base const& other);
_ptr_list_common_base& operator=(_ptr_list_common_base const& other);
};
template <typename T, typename CloneAllocator = heap_no_copy_allocator>
class ptr_list : protected _ptr_list_common_base<T, CloneAllocator>
{
typedef _ptr_list_common_base<T, CloneAllocator> _base_type;
public:
typedef T value_type;
typedef T& reference;
typedef T const& const_reference;
typedef _ptr_list_iterator<T const> const_iterator;
typedef _ptr_list_iterator<T> iterator;
typedef T* pointer;
typedef T const* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef CloneAllocator clone_allocator_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
ptr_list() {}
ptr_list(size_type n, const_reference t)
{
while(n--)
push_back(t);
}
template <typename InputIterator>
ptr_list(InputIterator i, InputIterator const& j
, clone_allocator_type const& alloc = clone_allocator_type()
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
: _base_type(alloc)
{
while(i != j)
{
push_back(*i);
++i;
}
}
ptr_list(ptr_list<T, CloneAllocator> const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
template <typename CloneAllocator1>
ptr_list(ptr_list<T, CloneAllocator1>const& other)
: _base_type()
{
insert(end(), other.begin(), other.end());
}
~ptr_list()
{
clear();
}
ptr_list<T, CloneAllocator>& operator=(ptr_list<T, CloneAllocator>const& other)
{
clear();
insert(end(), other.begin(), other.end());
return *this;
}
void clear()
{
for(iterator first = begin(), last = end(); first != last; ++first)
this->_delete_clone(&*first);
eina_list_free(this->_impl._list);
this->_impl._list = 0;
}
std::size_t size() const
{
return eina_list_count(this->_impl._list);
}
bool empty() const
{
return size() == 0u;
}
clone_allocator_type get_clone_allocator() const
{
return clone_allocator_type(this->_get_clone_allocator());
}
void push_back(const_reference a)
{
push_back(this->_new_clone(a));
}
void push_back(pointer p)
{
std::auto_ptr<value_type> p1(p);
push_back(p1);
}
void push_back(std::auto_ptr<T>& p)
{
Eina_List* new_list = eina_list_append(this->_impl._list, p.get());
if(new_list)
{
this->_impl._list = new_list;
p.release();
}
else
throw std::bad_alloc();
}
void push_front(const_reference a)
{
push_front(this->new_clone(a));
}
void push_front(pointer p)
{
std::auto_ptr<value_type> p1(p);
push_front(p1);
}
void push_front(std::auto_ptr<T>& p)
{
Eina_List* new_list = eina_list_prepend(this->_impl._list, p.get());
if(new_list)
{
this->_impl._list = new_list;
p.release();
}
else
throw std::bad_alloc();
}
void pop_back()
{
this->_impl._list = eina_list_remove_list(this->_impl._list, eina_list_last(this->_impl._list));
}
void pop_front()
{
this->_impl._list = eina_list_remove_list(this->_impl._list, this->_impl._list);
}
iterator insert(iterator i, value_type const& t)
{
return insert(i, this->_new_clone(t));
}
iterator insert(iterator i, pointer pv)
{
std::auto_ptr<value_type> p(pv);
return insert(i, p);
}
iterator insert(iterator i, std::auto_ptr<value_type>& p)
{
this->_impl._list = _eina_list_prepend_relative_list
(this->_impl._list, p.get(), i.native_handle());
if(this->_impl._list)
p.release();
else
throw std::bad_alloc();
return iterator(this->_impl._list
, i.native_handle()
? ::eina_list_prev(i.native_handle())
: ::eina_list_last(this->_impl._list)
);
}
iterator insert(iterator i, size_t n, value_type const& t)
{
iterator r = i;
if(n--)
r = insert(i, t);
while(n--)
insert(i, t);
return r;
}
iterator insert(iterator i, size_t n, pointer p)
{
iterator r = i;
if(n--)
r = insert(i, p);
while(n--)
insert(i, this->_new_clone(p));
return r;
}
template <typename InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
iterator r = p;
if(i != j)
{
r = insert(p, *i);
++i;
}
while(i != j)
{
insert(p, this->_new_clone(*i));
++i;
}
return r;
}
iterator erase(iterator q)
{
if(q.native_handle())
{
iterator r(this->_impl._list, eina_list_next(q.native_handle()));
this->_impl._list = eina_list_remove_list(this->_impl._list, q.native_handle());
return r;
}
else
return q;
}
iterator erase(iterator i, iterator j)
{
while(i != j)
i = erase(i);
if(j.native_handle())
return j;
else
return end();
}
template <typename InputIterator>
void assign(InputIterator i, InputIterator j
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
{
clear();
insert(end(), i, j);
}
void assign(size_type n, value_type const& t)
{
clear();
insert(end(), n, t);
}
value_type& back()
{
return *static_cast<pointer>(eina_list_data_get(eina_list_last(this->_impl._list)));
}
value_type const& back() const
{
return const_cast<ptr_list<T, CloneAllocator>&>(*this).back();
}
value_type& front()
{
return *static_cast<pointer>(eina_list_data_get(this->_impl._list));
}
value_type const& front() const
{
return const_cast<ptr_list<T, CloneAllocator>&>(*this).front();
}
const_iterator begin() const
{
return const_iterator(this->_impl._list, this->_impl._list);
}
const_iterator end() const
{
return const_iterator(this->_impl._list, 0);
}
iterator begin()
{
return iterator(this->_impl._list, this->_impl._list);
}
iterator end()
{
return iterator(this->_impl._list, 0);
}
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();
}
eina::iterator<T> ibegin()
{
return eina::iterator<T>( ::eina_list_iterator_new(this->_impl._list) );
}
eina::iterator<T> iend()
{
return eina::iterator<T>();
}
eina::iterator<T const> ibegin() const
{
return eina::iterator<T const>( ::eina_list_iterator_new(this->_impl._list) );
}
eina::iterator<T const> iend() const
{
return eina::iterator<T const>();
}
eina::iterator<T const> cibegin() const
{
return ibegin();
}
eina::iterator<T const> ciend() const
{
return iend();
}
void swap(ptr_list<T, CloneAllocator>& other)
{
std::swap(this->_impl._list, other._impl._list);
}
size_type max_size() const { return -1; }
Eina_List* native_handle()
{
return this->_impl._list;
}
Eina_List const* native_handle() const
{
return this->_impl._list;
}
eina::accessor<T const> accessor() const
{
return eina::accessor<T const>(eina_list_accessor_new(this->_impl._list));
}
eina::accessor<T> accessor()
{
return eina::accessor<T>(eina_list_accessor_new(this->_impl._list));
}
};
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator==(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
{
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
template <typename T, typename CloneAllocator1, typename CloneAllocator2>
bool operator!=(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
{
return !(lhs == rhs);
}
template <typename T, typename CloneAllocator>
void swap(ptr_list<T, CloneAllocator>& lhs, ptr_list<T, CloneAllocator>& rhs)
{
lhs.swap(rhs);
}
} }
#endif

View File

@ -0,0 +1,26 @@
#ifndef EINA_REF_HH
#define EINA_REF_HH
#include <functional>
namespace efl { namespace eina {
using std::ref;
using std::cref;
using std::reference_wrapper;
template <typename T>
T& unref(T& t)
{
return t;
}
template <typename T>
T& unref(reference_wrapper<T> t)
{
return t.get();
}
}}
#endif

View File

@ -0,0 +1,205 @@
#ifndef _EINA_STRINGSHARE_HH
#define _EINA_STRINGSHARE_HH
#include <Eina.h>
#include <eina_type_traits.hh>
#include <cstring>
#include <stdexcept>
namespace efl { namespace eina {
struct steal_stringshare_ref_t {};
steal_stringshare_ref_t const steal_stringshare_ref = {};
struct stringshare
{
typedef char value_type;
typedef value_type& reference;
typedef value_type const& const_reference;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef const_pointer const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
stringshare()
: _string( ::eina_stringshare_add("") )
{}
stringshare(const char* str)
: _string( ::eina_stringshare_add(str) )
{
}
stringshare(char* str, steal_stringshare_ref_t)
: _string( str )
{
}
template <typename InputIterator>
stringshare(InputIterator i, InputIterator j
, typename eina::enable_if
<!eina::is_integral<InputIterator>::value
&& !eina::is_contiguous_iterator<InputIterator>::value
>::type* = 0)
{
std::string tmp;
while(i != j)
{
tmp.push_back(*i);
++i;
}
_string = ::eina_stringshare_add(tmp.c_str());
}
template <typename ContiguousMemoryIterator>
stringshare(ContiguousMemoryIterator i, ContiguousMemoryIterator j
, typename eina::enable_if
<eina::is_contiguous_iterator<ContiguousMemoryIterator>::value>::type* = 0)
: _string( ::eina_stringshare_add_length(&*i, j - i) )
{
}
~stringshare()
{
::eina_stringshare_del(_string);
}
stringshare(stringshare const& other)
: _string( eina_stringshare_ref(other._string) )
{}
stringshare& operator=(stringshare const& other)
{
::eina_stringshare_refplace(&_string, other._string);
return *this;
}
stringshare& operator=(const char* c_string)
{
::eina_stringshare_replace(&_string, c_string);
return *this;
}
const_iterator begin() const
{
return _string;
}
const_iterator end() const
{
return _string + size();
}
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(begin());
}
const_reverse_iterator rend() const
{
return const_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();
}
size_type size() const
{
return eina_stringshare_strlen(_string);
}
size_type length() const
{
return size();
}
size_type max_size() const
{
return -1;
}
bool empty() const
{
return _string[0] == 0;
}
const_reference operator[](size_type i) const
{
return _string[i];
}
const_reference at(size_type i) const
{
if(i < size())
return (*this)[i];
else
throw std::out_of_range("");
}
const_reference back() const
{
return _string[size()-1];
}
const_reference front() const
{
return _string[0];
}
void swap(stringshare& other)
{
std::swap(_string, other._string);
}
const char* c_str() const
{
return _string;
}
const char* data() const
{
return _string;
}
private:
Eina_Stringshare* _string;
};
template <>
struct is_contiguous_iterator<stringshare::const_iterator> : true_type {};
inline bool operator==(stringshare const& lhs, stringshare const& rhs)
{
return lhs.c_str() == rhs.c_str();
}
inline bool operator!=(stringshare const& lhs, stringshare const& rhs)
{
return !(lhs == rhs);
}
inline bool operator==(stringshare const& lhs, const char* rhs)
{
return lhs.c_str() == rhs || std::strcmp(lhs.c_str(), rhs) == 0;
}
inline bool operator!=(stringshare const& lhs, const char* rhs)
{
return !(lhs == rhs);
}
inline bool operator==(const char* lhs, stringshare const& rhs)
{
return rhs == lhs;
}
inline bool operator!=(const char* lhs, stringshare const& rhs)
{
return !(lhs == rhs);
}
} }
#endif

View File

@ -0,0 +1,356 @@
#ifndef EINA_THREAD_HH_
#define EINA_THREAD_HH_
#include <Eina.h>
#include <eina_error.hh>
#include <memory>
#include <iterator>
#include <cstdlib>
#include <cassert>
#include <iosfwd>
#include <functional>
#include <chrono>
#include <mutex>
#define EFL_EINA_BOOST_MOVABLE_BUT_NOT_COPYABLE(x)
#define EFL_EINA_BOOST_RV_REF(x) x const&
namespace efl { namespace eina {
struct mutex
{
typedef Eina_Lock* native_handle_type;
mutex()
{
::eina_lock_new(&_mutex);
}
~mutex()
{
::eina_lock_free(&_mutex);
}
void lock()
{
::Eina_Lock_Result r = ::eina_lock_take(&_mutex);
switch(r)
{
case EINA_LOCK_SUCCEED:
return;
case EINA_LOCK_DEADLOCK:
throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
, get_generic_category()));
default:
throw system_error(get_error_code());
}
}
bool try_lock()
{
::Eina_Lock_Result r = ::eina_lock_take_try(&_mutex);
switch(r)
{
case EINA_LOCK_SUCCEED:
return true;
case EINA_LOCK_FAIL:
return false;
case EINA_LOCK_DEADLOCK:
throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
, get_generic_category()));
default:
throw system_error(get_error_code());
}
}
void unlock()
{
::Eina_Lock_Result r = ::eina_lock_release(&_mutex);
switch(r)
{
case EINA_LOCK_SUCCEED:
return;
case EINA_LOCK_DEADLOCK:
throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
, get_generic_category()));
default:
throw system_error(get_error_code());
}
}
void debug()
{
::eina_lock_debug(&_mutex);
}
native_handle_type native_handle()
{
return &_mutex;
}
private:
mutex(mutex const&) = delete;
mutex& operator=(mutex const&) = delete;
Eina_Lock _mutex;
};
using std::lock_guard;
using std::unique_lock;
struct condition_variable
{
typedef Eina_Condition* native_handle_type;
condition_variable()
{
::eina_condition_new(&_cond, _mutex.native_handle());
}
~condition_variable()
{
::eina_condition_free(&_cond);
}
void notify_one()
{
eina::unique_lock<eina::mutex> l(_mutex);
Eina_Bool r = eina_condition_signal(&_cond);
if(!r)
throw eina::system_error(eina::get_error_code());
}
void notify_all()
{
eina::unique_lock<eina::mutex> l(_mutex);
Eina_Bool r = eina_condition_broadcast(&_cond);
if(!r)
throw eina::system_error(eina::get_error_code());
}
template <typename Lock>
void wait(Lock& lock)
{
eina::unique_lock<eina::mutex> l(_mutex);
lock.unlock();
::eina_condition_wait(&_cond);
lock.lock();
}
template <typename Lock, typename Predicate>
void wait(Lock& lock, Predicate p)
{
while(!p())
wait(lock);
}
native_handle_type native_handle()
{
return &_cond;
}
private:
condition_variable(condition_variable const&);
condition_variable& operator=(condition_variable const&);
mutex _mutex;
Eina_Condition _cond;
};
struct thread_id
{
thread_id() noexcept
: _raw(0u)
{
}
thread_id(Eina_Thread raw)
: _raw(raw) {}
friend inline bool operator==(thread_id lhs, thread_id rhs)
{
return lhs._raw == rhs._raw;
}
friend inline bool operator!=(thread_id lhs, thread_id rhs)
{
return lhs._raw != rhs._raw;
}
friend inline bool operator<(thread_id lhs, thread_id rhs)
{
return std::less<Eina_Thread>()(lhs._raw, rhs._raw);
}
private:
Eina_Thread _raw;
};
inline bool operator<=(thread_id lhs, thread_id rhs)
{
return (lhs == rhs) || lhs < rhs;
}
inline bool operator>(thread_id lhs, thread_id rhs)
{
return !(lhs <= rhs);
}
inline bool operator>=(thread_id lhs, thread_id rhs)
{
return !(lhs < rhs);
}
template <typename charT, typename Traits>
std::basic_ostream<charT, Traits>&
operator<<(std::basic_ostream<charT, Traits>& out, thread_id id)
{
return out << id._raw;
}
namespace _detail {
struct arguments
{
Eina_Lock mutex;
Eina_Condition condition;
bool started;
std::function<void()> function;
};
inline void* create_thread(void* data, Eina_Thread)
{
arguments* args = static_cast<arguments*>(data);
eina_lock_take(&args->mutex);
std::function<void()> f = std::move(args->function);
args->started = true;
eina_condition_signal(&args->condition);
eina_lock_release(&args->mutex);
f();
return 0;
}
}
struct thread
{
typedef thread_id id;
typedef Eina_Thread native_handle_type;
thread() noexcept
: _joinable(false), _raw(0u)
{
}
template <typename F, class ... Args>
explicit thread(F&& f, Args&&... args)
{
_detail::arguments arguments;
arguments.started = false;
arguments.function = std::bind(f, args...);
_joinable = true;
Eina_Bool r = ::eina_lock_new(&arguments.mutex);
if(!r) throw eina::system_error(eina::get_error_code());
r = ::eina_condition_new(&arguments.condition, &arguments.mutex);
if(!r) throw eina::system_error(eina::get_error_code());
if(!eina_thread_create
(&_raw, ::EINA_THREAD_NORMAL
, -1, &eina::_detail::create_thread, &arguments))
{
eina_condition_free(&arguments.condition);
eina_lock_free(&arguments.mutex);
throw eina::system_error(eina::get_error_code());
}
Eina_Lock_Result lr = ::eina_lock_take(&arguments.mutex);
if(lr != EINA_LOCK_SUCCEED)
throw eina::system_error(eina::get_error_code());
while(!arguments.started)
{
r = eina_condition_wait(&arguments.condition);
if(!r) throw eina::system_error(eina::get_error_code());
}
lr = eina_lock_release(&arguments.mutex);
if(lr != EINA_LOCK_SUCCEED)
throw eina::system_error(eina::get_error_code());
eina_condition_free(&arguments.condition);
eina_lock_free(&arguments.mutex);
}
thread(thread&& other)
: _joinable(other._joinable), _raw(other._raw)
{
}
thread& operator=(thread&& other)
{
_raw = other._raw;
_joinable = other._joinable;
return *this;
}
~thread()
{
assert(!joinable());
}
void swap(thread& other) noexcept
{
std::swap(_raw, other._raw);
}
bool joinable() const noexcept
{
return _joinable;
}
void join()
{
assert(joinable());
::eina_thread_join(_raw);
_joinable = false;
}
void detach()
{
assert(joinable());
_joinable = false;
}
id get_id() const noexcept
{
return id(_raw);
}
native_handle_type native_handle() const
{
return _raw;
}
static unsigned hardware_concurrency() noexcept
{
return ::eina_cpu_count();
}
private:
bool _joinable;
Eina_Thread _raw;
};
inline void swap(thread& lhs, thread& rhs)
{
lhs.swap(rhs);
}
namespace this_thread {
inline thread::id get_id()
{
return thread::id(eina_thread_self());
}
inline void yield() {}
template <typename Clock, typename Duration>
void sleep_until(std::chrono::time_point<Clock, Duration>const& abs_time);
template <typename Rep, typename Period>
void sleep_for(std::chrono::duration<Rep, Period>const& rel_time);
}
} }
namespace std {
template <typename T> struct hash;
template <>
struct hash< ::efl::eina::thread_id> : hash<unsigned long>
{};
}
#endif

View File

@ -0,0 +1,51 @@
#ifndef _EINA_TYPE_TRAITS_HH
#define _EINA_TYPE_TRAITS_HH
#include <type_traits>
#include <string>
#include <vector>
namespace efl { namespace eina {
using std::enable_if;
using std::is_integral;
using std::is_pod;
using std::is_const;
using std::remove_cv;
using std::true_type;
using std::false_type;
using std::remove_pointer;
using std::remove_reference;
template <typename T, typename Enable = void>
struct is_contiguous_iterator : false_type {};
template <>
struct is_contiguous_iterator<std::string::const_iterator> : true_type {};
template <>
struct is_contiguous_iterator<std::string::iterator> : true_type {};
template <>
struct is_contiguous_iterator<std::vector<char>::const_iterator> : true_type {};
template <>
struct is_contiguous_iterator<std::vector<char>::iterator> : true_type {};
template <bool, typename T, typename F>
struct if_c
{
typedef T type;
};
template <typename T, typename F>
struct if_c<false, T, F>
{
typedef F type;
};
template <typename U, typename T, typename F>
struct if_ : if_c<U::value, T, F>
{
};
} }
#endif

View File

@ -0,0 +1,371 @@
#ifndef _EFL_EINA_EINA_VALUE_HH
#define _EFL_EINA_EINA_VALUE_HH
#include <Eina.h>
#include <eina_stringshare.hh>
#include <eina_type_traits.hh>
namespace efl { namespace eina {
template <typename T>
struct _eina_value_traits_base;
template <typename T>
struct _eina_value_traits_aux;
// Indirection for uint64_t. uint64_t can be a typedef for unsigned
// long, so we can't specialize on the same template
template <>
struct _eina_value_traits_aux<uint64_t>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_UINT64;
}
};
template <typename T, typename Enable = void>
struct _eina_value_traits : _eina_value_traits_aux<T>
{
};
template <typename T>
struct _eina_value_traits_base
{
typedef T type;
static ::Eina_Value* create()
{
return eina_value_new(_eina_value_traits<T>::value_type());
}
static void set_type( ::Eina_Value* v)
{
eina_value_setup(v, _eina_value_traits<T>::value_type());
}
static void set( ::Eina_Value* v, type c)
{
::eina_value_set(v, c);
}
static type get( ::Eina_Value* v)
{
if(_eina_value_traits<T>::value_type() == eina_value_type_get(v))
{
type vv;
if(::eina_value_get(v, &vv))
return vv;
else
throw eina::system_error(eina::get_error_code());
}
else
throw eina::system_error(EINA_ERROR_VALUE_FAILED, eina::eina_error_category());
}
};
template <>
struct _eina_value_traits<unsigned char>
: _eina_value_traits_base<unsigned char>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_UCHAR;
}
};
template <>
struct _eina_value_traits<unsigned short>
: _eina_value_traits_base<unsigned short>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_USHORT;
}
};
template <>
struct _eina_value_traits<unsigned int>
: _eina_value_traits_base<unsigned int>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_UINT;
}
};
template <>
struct _eina_value_traits<unsigned long>
: _eina_value_traits_base<unsigned long>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_ULONG;
}
};
template <>
struct _eina_value_traits<char>
: _eina_value_traits_base<char>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_CHAR;
}
};
template <>
struct _eina_value_traits<short>
: _eina_value_traits_base<short>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_SHORT;
}
};
template <>
struct _eina_value_traits<int>
: _eina_value_traits_base<int>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_INT;
}
};
template <>
struct _eina_value_traits<long>
: _eina_value_traits_base<long>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_LONG;
}
};
template <>
struct _eina_value_traits<float>
: _eina_value_traits_base<float>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_FLOAT;
}
};
template <>
struct _eina_value_traits<double>
: _eina_value_traits_base<double>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_DOUBLE;
}
};
template <>
struct _eina_value_traits<stringshare>
: _eina_value_traits_base<stringshare>
{
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_STRINGSHARE;
}
static void set( ::Eina_Value* v, type c)
{
::eina_value_set(v, c.data());
}
static type get( ::Eina_Value* v)
{
char* c_str;
::eina_value_get(v, &c_str);
return stringshare(c_str, steal_stringshare_ref);
}
};
template <>
struct _eina_value_traits<std::string>
: _eina_value_traits_base<std::string>
{
typedef typename _eina_value_traits_base<std::string>::type type;
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_STRING;
}
static void set( ::Eina_Value* v, type c)
{
::eina_value_set(v, c.c_str());
}
static type get( ::Eina_Value* v)
{
char* c_str;
::eina_value_get(v, &c_str);
std::string r(c_str);
::free(c_str);
return r;
}
};
template <typename T>
struct _eina_value_traits<T[], typename eina::enable_if<eina::is_pod<T>::value>::type>
: _eina_value_traits_base<T[]>
{
typedef typename _eina_value_traits_base<T[]>::type type;
static ::Eina_Value_Type const* value_type()
{
return EINA_VALUE_TYPE_ARRAY;
}
static void set( ::Eina_Value* v, type c)
{
::eina_value_set(v, c.c_str());
}
static type get( ::Eina_Value* v)
{
char* c_str;
::eina_value_get(v, &c_str);
std::string r(c_str);
::free(c_str);
return r;
}
};
class eina_value
{
template <typename T>
void primitive_init(T v)
{
_raw = _eina_value_traits<T>::create();
_eina_value_traits<T>::set(_raw, v);
}
public:
eina_value()
: _raw(_eina_value_traits<char>::create())
{
}
eina_value(char v)
{
primitive_init(v);
}
eina_value(short v)
{
primitive_init(v);
}
eina_value(int v)
{
primitive_init(v);
}
eina_value(long v)
{
primitive_init(v);
}
eina_value(unsigned char v)
{
primitive_init(v);
}
eina_value(unsigned short v)
{
primitive_init(v);
}
eina_value(unsigned int v)
{
primitive_init(v);
}
eina_value(unsigned long v)
{
primitive_init(v);
}
eina_value(float v)
{
primitive_init(v);
}
eina_value(double v)
{
primitive_init(v);
}
~eina_value()
{
eina_value_free(_raw);
}
eina_value(eina_value const& other)
: _raw(_eina_value_traits<char>::create())
{
if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
throw eina::system_error(eina::get_error_code());
}
eina_value& operator=(eina_value const& other)
{
eina_value_flush(_raw);
if(!eina_value_copy(const_cast<Eina_Value const*>(other._raw), _raw))
throw eina::system_error(eina::get_error_code());
return *this;
}
void swap(eina_value& other)
{
std::swap(_raw, other._raw);
}
typedef Eina_Value* native_handle_type;
native_handle_type native_handle() const
{
return _raw;
}
typedef Eina_Value_Type const* type_info_t;
type_info_t type_info() const
{
return ::eina_value_type_get(_raw);
}
private:
::Eina_Value* _raw;
template <typename T>
friend T get(eina_value const& v)
{
return _eina_value_traits<T>::get(v._raw);
}
};
inline void swap(eina_value& lhs, eina_value& rhs)
{
lhs.swap(rhs);
}
inline bool operator==(eina_value const& lhs, eina_value const& rhs)
{
return lhs.type_info() == rhs.type_info()
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) == 0;
}
inline bool operator<(eina_value const& lhs, eina_value const& rhs)
{
return std::less<Eina_Value_Type const*>()(lhs.type_info(), rhs.type_info())
|| (lhs.type_info() == rhs.type_info()
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) < 0);
}
inline bool operator>(eina_value const& lhs, eina_value const& rhs)
{
return std::less<Eina_Value_Type const*>()(rhs.type_info(), lhs.type_info())
|| (rhs.type_info() == lhs.type_info()
&& eina_value_compare(lhs.native_handle(), rhs.native_handle()) > 0);
}
inline bool operator<=(eina_value const& lhs, eina_value const& rhs)
{
return !(lhs > rhs);
}
inline bool operator>=(eina_value const& lhs, eina_value const& rhs)
{
return !(lhs < rhs);
}
inline bool operator!=(eina_value const& lhs, eina_value const& rhs)
{
return !(lhs == rhs);
}
} }
#endif

View File

@ -0,0 +1,125 @@
#include "Eina.hh"
#include <cassert>
#include <algorithm>
#include <check.h>
void eina_test_inlist(TCase* tc);
void eina_test_inarray(TCase* tc);
void eina_test_ptrlist(TCase* tc);
void eina_test_ptrarray(TCase* tc);
void eina_test_iterator(TCase* tc);
void eina_test_stringshare(TCase* tc);
void eina_test_error(TCase* tc);
void eina_test_accessor(TCase* tc);
void eina_test_thread(TCase* tc);
void eina_test_eina_value(TCase* tc);
typedef struct _Eina_Test_Case Eina_Test_Case;
struct _Eina_Test_Case
{
const char *test_case;
void (*build)(TCase *tc);
};
static const Eina_Test_Case etc[] = {
{ "Ptr_List", eina_test_ptrlist },
{ "Ptr_Array", eina_test_ptrarray },
{ "Inlist", eina_test_inlist },
{ "Inarray", eina_test_inarray },
{ "Iterator", eina_test_iterator },
{ "Stringshare", eina_test_stringshare },
{ "Error", eina_test_error },
{ "Accessor", eina_test_accessor },
{ "Thread", eina_test_thread },
{ "EinaValue", eina_test_eina_value },
{ NULL, NULL }
};
static void
_list_tests(void)
{
const Eina_Test_Case *itr = etc;
fputs("Available Test Cases:\n", stderr);
for (; itr->test_case; itr++)
fprintf(stderr, "\t%s\n", itr->test_case);
}
static Eina_Bool
_use_test(int argc, const char **argv, const char *test_case)
{
if (argc < 1)
return 1;
for (; argc > 0; argc--, argv++)
if (strcmp(test_case, *argv) == 0)
return 1;
return 0;
}
Suite *
eina_build_suite(int argc, const char **argv)
{
TCase *tc;
Suite *s;
int i;
s = suite_create("Eina");
for (i = 0; etc[i].test_case; ++i)
{
if (!_use_test(argc, argv, etc[i].test_case))
continue;
tc = tcase_create(etc[i].test_case);
tcase_set_timeout(tc, 0);
etc[i].build(tc);
suite_add_tcase(s, tc);
}
return s;
}
int main(int argc, char* argv[])
{
Suite *s;
SRunner *sr;
int i, failed_count;
for (i = 1; i < argc; i++)
if ((strcmp(argv[i], "-h") == 0) ||
(strcmp(argv[i], "--help") == 0))
{
fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
argv[0]);
_list_tests();
return 0;
}
else if ((strcmp(argv[i], "-l") == 0) ||
(strcmp(argv[i], "--list") == 0))
{
_list_tests();
return 0;
}
putenv(const_cast<char*>("EFL_RUN_IN_TREE=1"));
s = eina_build_suite(argc - 1, (const char **)argv + 1);
sr = srunner_create(s);
srunner_set_xml(sr, TESTS_BUILD_DIR "/check-results.xml");
eina_init();
srunner_run_all(sr, CK_ENV);
failed_count = srunner_ntests_failed(sr);
srunner_free(sr);
eina_shutdown();
return (failed_count == 0) ? 0 : 255;
}

View File

@ -0,0 +1,102 @@
#include "Eina.hh"
#include <algorithm>
#include <check.h>
START_TEST(eina_cxx_accessor_indexing)
{
efl::eina::ptr_list<int> list;
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
list.push_back(new int(20));
efl::eina::accessor<int> accessor(list.accessor());
ck_assert(accessor[0] == 5);
ck_assert(accessor[1] == 10);
ck_assert(accessor[2] == 15);
ck_assert(accessor[3] == 20);
}
END_TEST
START_TEST(eina_cxx_accessor_iterator)
{
efl::eina::ptr_list<int> list;
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
list.push_back(new int(20));
std::size_t pos = 0u;
for(efl::eina::accessor_iterator<int> first (list.accessor())
, last (list.accessor(), list.size()); first != last; ++first, ++pos)
{
ck_assert(pos != 0u || *first == 5);
ck_assert(pos != 1u || *first == 10);
ck_assert(pos != 2u || *first == 15);
ck_assert(pos != 3u || *first == 20);
}
}
END_TEST
START_TEST(eina_cxx_accessor_relops)
{
efl::eina::ptr_list<int> list;
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
list.push_back(new int(20));
efl::eina::accessor_iterator<int> first (list.accessor())
, second(list.accessor(), 1u)
, third(list.accessor(), 2u)
, fourth(list.accessor(), 3u)
;
ck_assert(!(first < first)); ck_assert(first < second);
ck_assert(first < third); ck_assert(first < fourth);
ck_assert(!(second < first)); ck_assert(!(second < second));
ck_assert(second < third); ck_assert(second < fourth);
ck_assert(!(third < first)); ck_assert(!(third < second));
ck_assert(!(third < third)); ck_assert(third < fourth);
ck_assert(!(fourth < first)); ck_assert(!(fourth < second));
ck_assert(!(fourth < third)); ck_assert(!(fourth < fourth));
ck_assert(first <= first); ck_assert(first <= second);
ck_assert(first <= third); ck_assert(first <= fourth);
ck_assert(!(second <= first)); ck_assert(second <= second);
ck_assert(second <= third); ck_assert(second <= fourth);
ck_assert(!(third <= first)); ck_assert(!(third <= second));
ck_assert(third <= third); ck_assert(third <= fourth);
ck_assert(!(fourth <= first)); ck_assert(!(fourth <= second));
ck_assert(!(fourth <= third)); ck_assert(fourth <= fourth);
ck_assert(!(first > first)); ck_assert(!(first > second));
ck_assert(!(first > third)); ck_assert(!(first > fourth));
ck_assert(second > first); ck_assert(!(second > second));
ck_assert(!(second > third)); ck_assert(!(second > fourth));
ck_assert(third > first); ck_assert(third > second);
ck_assert(!(third > third)); ck_assert(!(third > fourth));
ck_assert(fourth > first); ck_assert(fourth > second);
ck_assert(fourth > third); ck_assert(!(fourth > fourth));
ck_assert(first >= first); ck_assert(!(first >= second));
ck_assert(!(first >= third)); ck_assert(!(first >= fourth));
ck_assert(second >= first); ck_assert(second >= second);
ck_assert(!(second >= third)); ck_assert(!(second >= fourth));
ck_assert(third >= first); ck_assert(third >= second);
ck_assert(third >= third); ck_assert(!(third >= fourth));
ck_assert(fourth >= first); ck_assert(fourth >= second);
ck_assert(fourth >= third); ck_assert(fourth >= fourth);
}
END_TEST
void
eina_test_accessor(TCase* tc)
{
tcase_add_test(tc, eina_cxx_accessor_indexing);
tcase_add_test(tc, eina_cxx_accessor_iterator);
tcase_add_test(tc, eina_cxx_accessor_relops);
}

View File

@ -0,0 +1,191 @@
#include "Eina.hh"
#include <check.h>
START_TEST(eina_cxx_eina_value_constructors)
{
efl::eina::eina_init init;
efl::eina::eina_value v;
char c = 'c';
efl::eina::eina_value vchar(c);
short s = 5;
efl::eina::eina_value vshort(s);
efl::eina::eina_value vint(5);
efl::eina::eina_value vlong(5l);
unsigned char uc = 'b';
efl::eina::eina_value vuchar(uc);
unsigned short us = 5;
efl::eina::eina_value vushort(us);
efl::eina::eina_value vuint(5u);
efl::eina::eina_value vulong(5ul);
efl::eina::eina_value vu64(uint64_t(5ul));
efl::eina::eina_value vfloat(5.0f);
efl::eina::eina_value vdouble(5.0);
}
END_TEST
START_TEST(eina_cxx_eina_value_get)
{
efl::eina::eina_init init;
char c = 'c';
efl::eina::eina_value vchar(c);
ck_assert(efl::eina::get<char>(vchar) == 'c');
short s = 5;
efl::eina::eina_value vshort(s);
ck_assert(efl::eina::get<short>(vshort) == 5);
efl::eina::eina_value vint(6);
ck_assert(efl::eina::get<int>(vint) == 6);
efl::eina::eina_value vlong(7l);
ck_assert(efl::eina::get<long>(vlong) == 7l);
unsigned char uc = 'b';
efl::eina::eina_value vuchar(uc);
ck_assert(efl::eina::get<unsigned char>(vuchar) == 'b');
unsigned short us = 8;
efl::eina::eina_value vushort(us);
ck_assert(efl::eina::get<unsigned short>(vushort) == 8);
efl::eina::eina_value vuint(9u);
ck_assert(efl::eina::get<unsigned int>(vuint) == 9u);
efl::eina::eina_value vulong(10ul);
ck_assert(efl::eina::get<unsigned long>(vulong) == 10ul);
efl::eina::eina_value vu64((uint64_t)10ul);
ck_assert(efl::eina::get<uint64_t>(vu64) == 10ul);
efl::eina::eina_value vfloat(11.0f);
ck_assert(efl::eina::get<float>(vfloat) == 11.0f);
efl::eina::eina_value vdouble(12.0);
ck_assert(efl::eina::get<double>(vdouble) == 12.0f);
}
END_TEST
START_TEST(eina_cxx_eina_value_wrong_get)
{
efl::eina::eina_init init;
char c = 'c';
efl::eina::eina_value vchar(c);
try
{
efl::eina::get<int>(vchar);
std::abort();
}
catch(efl::eina::system_error const&)
{
}
}
END_TEST
START_TEST(eina_cxx_eina_value_comparison_operators)
{
efl::eina::eina_init init;
efl::eina::eina_value v;
char c = 5;
efl::eina::eina_value vchar(c);
short s = 5;
efl::eina::eina_value vshort(s);
efl::eina::eina_value vint(5);
efl::eina::eina_value vlong(5l);
unsigned char uc = 5;
efl::eina::eina_value vuchar(uc);
unsigned short us = 5;
efl::eina::eina_value vushort(us);
efl::eina::eina_value vuint(5u);
efl::eina::eina_value vulong(5ul);
efl::eina::eina_value vu64((uint64_t)5ul);
efl::eina::eina_value vfloat(5.0f);
efl::eina::eina_value vdouble(5.0);
ck_assert(vchar == vchar);
ck_assert(vshort == vshort);
ck_assert(vint == vint);
ck_assert(vlong == vlong);
ck_assert(vuchar == vuchar);
ck_assert(vushort == vushort);
ck_assert(vuint == vuint);
ck_assert(vulong == vulong);
ck_assert(vu64 == vu64);
ck_assert(vfloat == vfloat);
ck_assert(vdouble == vdouble);
ck_assert(vchar != vshort);
ck_assert(vshort != vint);
ck_assert(vint != vlong);
ck_assert(vlong != vuchar);
ck_assert(vuchar != vushort);
ck_assert(vushort != vuint);
ck_assert(vuint != vulong);
ck_assert(vulong != vfloat);
ck_assert(vfloat != vdouble);
ck_assert(vdouble != vchar);
ck_assert(vchar != vuchar);
ck_assert(vshort != vushort);
ck_assert(vint != vuint);
ck_assert(vlong != vulong);
ck_assert(vfloat != vdouble);
ck_assert(vdouble != vfloat);
}
END_TEST
START_TEST(eina_cxx_eina_value_copying)
{
char c = 5;
efl::eina::eina_value vchar(c);
efl::eina::eina_value vchar2(vchar);
ck_assert(vchar == vchar2);
ck_assert(efl::eina::get<char>(vchar) == 5);
ck_assert(efl::eina::get<char>(vchar2) == 5);
efl::eina::eina_value vint(10);
vchar = vint;
ck_assert(vchar != vchar2);
ck_assert(vint == vchar);
ck_assert(efl::eina::get<int>(vchar) == 10);
ck_assert(efl::eina::get<int>(vint) == 10);
}
END_TEST
void
eina_test_eina_value(TCase* tc)
{
tcase_add_test(tc, eina_cxx_eina_value_constructors);
tcase_add_test(tc, eina_cxx_eina_value_get);
tcase_add_test(tc, eina_cxx_eina_value_wrong_get);
tcase_add_test(tc, eina_cxx_eina_value_comparison_operators);
tcase_add_test(tc, eina_cxx_eina_value_copying);
}

View File

@ -0,0 +1,72 @@
#include "Eina.hh"
#include <check.h>
Eina_Error my_error, my_error_2;
START_TEST(eina_cxx_get_error)
{
efl::eina::eina_init eina_init;
my_error = ::eina_error_msg_static_register("Message 1");
::eina_error_set(0);
efl::eina::error_code ec1 = efl::eina::get_error_code();
ck_assert(!ec1);
::eina_error_set(my_error);
efl::eina::error_code ec2 = efl::eina::get_error_code();
ck_assert(!!ec2);
ck_assert(ec2.message() == "Message 1");
::eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
efl::eina::error_code ec3 = efl::eina::get_error_code();
ck_assert(!!ec3);
ck_assert(ec3.message() == "Out of memory");
}
END_TEST
START_TEST(eina_cxx_throw_on_error)
{
efl::eina::eina_init eina_init;
::eina_error_set(my_error_2);
my_error_2 = ::eina_error_msg_static_register("Message 2");
::eina_error_set(0);
try
{
efl::eina::throw_on_error();
}
catch(std::exception const&)
{
std::abort();
}
::eina_error_set(my_error_2);
try
{
efl::eina::throw_on_error();
std::abort();
}
catch(efl::eina::system_error const& e)
{
ck_assert(e.code().value() == my_error_2);
ck_assert(e.code().message() == "Message 2");
ck_assert(!efl::eina::get_error_code());
}
}
END_TEST
void
eina_test_error(TCase *tc)
{
tcase_add_test(tc, eina_cxx_get_error);
tcase_add_test(tc, eina_cxx_throw_on_error);
}

View File

@ -0,0 +1,388 @@
#include "Eina.hh"
#include <algorithm>
#include <functional>
#include <iostream>
#include <check.h>
START_TEST(eina_cxx_inarray_pod_push_back)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array;
array.push_back(5);
array.push_back(10);
array.push_back(15);
int result[] = {5, 10, 15};
ck_assert(array.size() == 3);
ck_assert(std::equal(array.begin(), array.end(), result));
}
END_TEST
START_TEST(eina_cxx_inarray_pod_pop_back)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array;
array.push_back(5);
array.push_back(10);
array.push_back(15);
array.pop_back();
int result[] = {5, 10};
ck_assert(array.size() == 2);
ck_assert(std::equal(array.begin(), array.end(), result));
}
END_TEST
START_TEST(eina_cxx_inarray_pod_insert)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array;
efl::eina::inarray<int>::iterator it;
it = array.insert(array.end(), 5); // first element
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
it = array.insert(array.end(), 10); // equivalent to push_back
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
it = array.insert(array.begin(), 15); // equivalent to push_front
ck_assert(it == array.begin());
it = array.end();
--it;
array.insert(it, 20); // insert before the last element
int result[] = {15, 5, 20, 10};
ck_assert(array.size() == 4);
ck_assert(std::equal(array.begin(), array.end(), result));
efl::eina::inarray<int> array2;
it = array2.insert(array2.end(), array.begin(), array.end());
ck_assert(it == array2.begin());
ck_assert(array == array2);
efl::eina::inarray<int> array3;
array3.push_back(1);
it = array3.insert(array3.end(), array.begin(), array.end());
ck_assert(array3.size() == 5);
ck_assert(array3.front() == 1);
it = array3.begin();
++it;
ck_assert(std::equal(it, array3.end(), array.begin()));
efl::eina::inarray<int> array4;
array4.push_back(1);
it = array4.insert(array4.begin(), array.begin(), array.end());
ck_assert(array4.size() == 5);
ck_assert(array4.back() == 1);
ck_assert(std::equal(array.begin(), array.end(), array4.begin()));
}
END_TEST
START_TEST(eina_cxx_inarray_pod_constructors)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array1;
ck_assert(array1.empty());
efl::eina::inarray<int> array2(10, 5);
ck_assert(array2.size() == 10);
ck_assert(std::find_if(array2.begin(), array2.end()
, std::not1(std::bind1st(std::equal_to<int>(), 5))) == array2.end());
efl::eina::inarray<int> array3(array2);
ck_assert(array2 == array3);
efl::eina::inarray<int> array4(array2.begin(), array2.end());
ck_assert(array2 == array4);
}
END_TEST
START_TEST(eina_cxx_inarray_pod_erase)
{
efl::eina::eina_init eina_init;
efl::eina::inarray<int> array1;
array1.push_back(5);
array1.push_back(10);
array1.push_back(15);
array1.push_back(20);
array1.push_back(25);
array1.push_back(30);
efl::eina::inarray<int>::iterator it = array1.begin(), it2;
it = array1.erase(it);
ck_assert(it == array1.begin());
ck_assert(array1.size() == 5);
ck_assert(array1.front() == 10);
it = array1.begin() + 1;
ck_assert(*it == 15);
it = array1.erase(it);
ck_assert(*it == 20);
ck_assert(array1.size() == 4);
it = array1.end() - 1;
it = array1.erase(it);
ck_assert(it == array1.end());
ck_assert(array1.size() == 3);
ck_assert(array1.back() == 25);
it = array1.begin() + 1;
it2 = array1.end() - 1;
it = array1.erase(it, it2);
it2 = array1.end() -1;
ck_assert(it == it2);
ck_assert(array1.size() == 2);
ck_assert(array1.front() == 10);
ck_assert(array1.back() == 25);
}
END_TEST
unsigned int constructors_called = 0u;
unsigned int destructors_called = 0u;
struct non_pod
{
non_pod(int x)
: x(new int(x))
{
++::constructors_called;
}
~non_pod()
{
++::destructors_called;
delete x;
}
non_pod(non_pod const& other)
{
++::constructors_called;
x = new int(*other.x);
}
non_pod& operator=(non_pod const& other)
{
delete x;
x = new int(*other.x);
return *this;
}
int* x;
};
bool operator==(non_pod lhs, non_pod rhs)
{
return *lhs.x == *rhs.x;
}
START_TEST(eina_cxx_inarray_nonpod_push_back)
{
efl::eina::eina_init eina_init;
{
efl::eina::inarray<non_pod> array;
array.push_back(5);
array.push_back(10);
array.push_back(15);
int result[] = {5, 10, 15};
ck_assert(array.size() == 3);
ck_assert(std::equal(array.begin(), array.end(), result));
}
std::cout << "constructors called " << ::constructors_called
<< "\ndestructors called " << ::destructors_called << std::endl;
ck_assert(::constructors_called == ::destructors_called);
::constructors_called = ::destructors_called = 0;
}
END_TEST
START_TEST(eina_cxx_inarray_nonpod_pop_back)
{
{
efl::eina::eina_init eina_init;
efl::eina::inarray<non_pod> array;
array.push_back(5);
array.push_back(10);
array.push_back(15);
array.pop_back();
int result[] = {5, 10};
ck_assert(array.size() == 2);
ck_assert(std::equal(array.begin(), array.end(), result));
}
std::cout << "constructors called " << ::constructors_called
<< "\ndestructors called " << ::destructors_called << std::endl;
ck_assert(::constructors_called == ::destructors_called);
::constructors_called = ::destructors_called = 0;
}
END_TEST
START_TEST(eina_cxx_inarray_nonpod_insert)
{
{
efl::eina::eina_init eina_init;
efl::eina::inarray<non_pod> array;
efl::eina::inarray<non_pod>::iterator it;
it = array.insert(array.end(), 5); // first element
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
it = array.insert(array.end(), 10); // equivalent to push_back
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
it = array.insert(array.begin(), 15); // equivalent to push_front
ck_assert(it == array.begin());
it = array.end();
--it;
array.insert(it, 20); // insert before the last element
int result[] = {15, 5, 20, 10};
ck_assert(array.size() == 4);
ck_assert(std::equal(array.begin(), array.end(), result));
efl::eina::inarray<non_pod> array2;
it = array2.insert(array2.end(), array.begin(), array.end());
ck_assert(it == array2.begin());
ck_assert(array == array2);
efl::eina::inarray<non_pod> array3;
array3.push_back(1);
it = array3.insert(array3.end(), array.begin(), array.end());
ck_assert(array3.size() == 5);
ck_assert(array3.front() == 1);
it = array3.begin();
++it;
ck_assert(std::equal(it, array3.end(), array.begin()));
efl::eina::inarray<non_pod> array4;
array4.push_back(1);
it = array4.insert(array4.begin(), array.begin(), array.end());
ck_assert(array4.size() == 5);
ck_assert(array4.back() == 1);
ck_assert(std::equal(array.begin(), array.end(), array4.begin()));
}
std::cout << "constructors called " << ::constructors_called
<< "\ndestructors called " << ::destructors_called << std::endl;
ck_assert(::constructors_called == ::destructors_called);
::constructors_called = ::destructors_called = 0;
}
END_TEST
START_TEST(eina_cxx_inarray_nonpod_constructors)
{
{
efl::eina::eina_init eina_init;
efl::eina::inarray<non_pod> array1;
ck_assert(array1.empty());
efl::eina::inarray<non_pod> array2(10, 5);
ck_assert(array2.size() == 10);
ck_assert(std::find_if(array2.begin(), array2.end()
, std::not1(std::bind1st(std::equal_to<non_pod>(), 5))) == array2.end());
efl::eina::inarray<non_pod> array3(array2);
ck_assert(array2 == array3);
efl::eina::inarray<non_pod> array4(array2.begin(), array2.end());
ck_assert(array2 == array4);
}
std::cout << "constructors called " << ::constructors_called
<< "\ndestructors called " << ::destructors_called << std::endl;
ck_assert(::constructors_called == ::destructors_called);
::constructors_called = ::destructors_called = 0;
}
END_TEST
START_TEST(eina_cxx_inarray_nonpod_erase)
{
{
efl::eina::eina_init eina_init;
efl::eina::inarray<non_pod> array1;
array1.push_back(5);
array1.push_back(10);
array1.push_back(15);
array1.push_back(20);
array1.push_back(25);
array1.push_back(30);
efl::eina::inarray<non_pod>::iterator it = array1.begin(), it2;
it = array1.erase(it);
ck_assert(it == array1.begin());
ck_assert(array1.size() == 5);
ck_assert(array1.front() == 10);
it = array1.begin() + 1;
ck_assert(*it == 15);
it = array1.erase(it);
ck_assert(*it == 20);
ck_assert(array1.size() == 4);
it = array1.end() - 1;
it = array1.erase(it);
ck_assert(it == array1.end());
ck_assert(array1.size() == 3);
ck_assert(array1.back() == 25);
it = array1.begin() + 1;
it2 = array1.end() - 1;
it = array1.erase(it, it2);
it2 = array1.end() -1;
ck_assert(it == it2);
ck_assert(array1.size() == 2);
ck_assert(array1.front() == 10);
ck_assert(array1.back() == 25);
}
std::cout << "constructors called " << ::constructors_called
<< "\ndestructors called " << ::destructors_called << std::endl;
ck_assert(::constructors_called == ::destructors_called);
::constructors_called = ::destructors_called = 0;
}
END_TEST
void
eina_test_inarray(TCase *tc)
{
tcase_add_test(tc, eina_cxx_inarray_pod_push_back);
tcase_add_test(tc, eina_cxx_inarray_pod_pop_back);
tcase_add_test(tc, eina_cxx_inarray_pod_insert);
tcase_add_test(tc, eina_cxx_inarray_pod_erase);
tcase_add_test(tc, eina_cxx_inarray_pod_constructors);
tcase_add_test(tc, eina_cxx_inarray_nonpod_push_back);
tcase_add_test(tc, eina_cxx_inarray_nonpod_pop_back);
tcase_add_test(tc, eina_cxx_inarray_nonpod_insert);
tcase_add_test(tc, eina_cxx_inarray_nonpod_erase);
tcase_add_test(tc, eina_cxx_inarray_nonpod_constructors);
}

View File

@ -0,0 +1,212 @@
#include "Eina.hh"
#include <algorithm>
#include <functional>
#include <check.h>
START_TEST(eina_cxx_inlist_push_back)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list;
list.push_back(5);
list.push_back(10);
list.push_back(15);
int result[] = {5, 10, 15};
ck_assert(list.size() == 3);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_inlist_pop_back)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list;
list.push_back(5);
list.push_back(10);
list.push_back(15);
list.pop_back();
int result[] = {5, 10};
ck_assert(list.size() == 2);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_inlist_push_front)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list;
list.push_front(5);
list.push_front(10);
list.push_front(15);
int result[] = {15, 10, 5};
ck_assert(list.size() == 3);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_inlist_pop_front)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list;
list.push_front(5);
list.push_front(10);
list.push_front(15);
list.pop_front();
int result[] = {10, 5};
ck_assert(list.size() == 2);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_inlist_insert)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list;
efl::eina::inlist<int>::iterator it;
it = list.insert(list.end(), 5); // first element
ck_assert(it != list.end());
++it;
ck_assert(it == list.end());
it = list.insert(list.end(), 10); // equivalent to push_back
ck_assert(it != list.end());
++it;
ck_assert(it == list.end());
it = list.insert(list.begin(), 15); // equivalent to push_front
ck_assert(it == list.begin());
it = list.end();
--it;
list.insert(it, 20); // insert before the last element
int result[] = {15, 5, 20, 10};
ck_assert(list.size() == 4);
ck_assert(std::equal(list.begin(), list.end(), result));
efl::eina::inlist<int> list2;
it = list2.insert(list2.end(), list.begin(), list.end());
ck_assert(it == list2.begin());
ck_assert(list == list2);
efl::eina::inlist<int> list3;
list3.push_back(1);
it = list3.insert(list3.end(), list.begin(), list.end());
ck_assert(list3.size() == 5);
ck_assert(list3.front() == 1);
it = list3.begin();
++it;
ck_assert(std::equal(it, list3.end(), list.begin()));
efl::eina::inlist<int> list4;
list4.push_back(1);
it = list4.insert(list4.begin(), list.begin(), list.end());
ck_assert(list4.size() == 5);
ck_assert(list4.back() == 1);
ck_assert(std::equal(list.begin(), list.end(), list4.begin()));
}
END_TEST
START_TEST(eina_cxx_inlist_constructors)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list1;
ck_assert(list1.empty());
efl::eina::inlist<int> list2(10, 5);
ck_assert(list2.size() == 10);
ck_assert(std::find_if(list2.begin(), list2.end()
, std::not1(std::bind1st(std::equal_to<int>(), 5))) == list2.end());
efl::eina::inlist<int> list3(list2);
ck_assert(list2 == list3);
efl::eina::inlist<int> list4(list2.begin(), list2.end());
ck_assert(list2 == list4);
}
END_TEST
START_TEST(eina_cxx_inlist_erase)
{
efl::eina::eina_init eina_init;
efl::eina::inlist<int> list1;
list1.push_back(5);
list1.push_back(10);
list1.push_back(15);
list1.push_back(20);
list1.push_back(25);
list1.push_back(30);
efl::eina::inlist<int>::iterator it = list1.begin(), it2;
it = list1.erase(it);
ck_assert(it == list1.begin());
ck_assert(list1.size() == 5);
ck_assert(list1.front() == 10);
it = list1.begin();
it2 = list1.begin();
++it;
++it2; ++it2;
ck_assert(*it2 == 20);
it = list1.erase(it);
ck_assert(it == it2);
ck_assert(list1.size() == 4);
ck_assert(*it2 == 20);
it = list1.end();
--it;
it = list1.erase(it);
ck_assert(it == list1.end());
ck_assert(list1.size() == 3);
ck_assert(list1.back() == 25);
it = list1.begin();
++it;
it2 = list1.end();
--it2;
it = list1.erase(it, it2);
it2 = list1.end();
--it2;
ck_assert(it == it2);
ck_assert(list1.size() == 2);
ck_assert(list1.front() == 10);
ck_assert(list1.back() == 25);
}
END_TEST
void
eina_test_inlist(TCase *tc)
{
tcase_add_test(tc, eina_cxx_inlist_push_back);
tcase_add_test(tc, eina_cxx_inlist_push_front);
tcase_add_test(tc, eina_cxx_inlist_pop_back);
tcase_add_test(tc, eina_cxx_inlist_pop_front);
tcase_add_test(tc, eina_cxx_inlist_insert);
tcase_add_test(tc, eina_cxx_inlist_erase);
tcase_add_test(tc, eina_cxx_inlist_constructors);
}

View File

@ -0,0 +1,34 @@
#include "Eina.hh"
#include <algorithm>
#include <check.h>
START_TEST(eina_cxx_iterator_equal)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
ck_assert(list.size() == 0);
ck_assert(list.empty());
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
list.push_back(new int(20));
efl::eina::iterator<int> iterator = list.ibegin()
, last_iterator = list.iend();
int result[] = {5, 10, 15, 20};
ck_assert(std::equal(iterator, last_iterator, result));
}
END_TEST
void
eina_test_iterator(TCase *tc)
{
tcase_add_test(tc, eina_cxx_iterator_equal);
}

View File

@ -0,0 +1,180 @@
#include "Eina.hh"
#include <algorithm>
#include <check.h>
START_TEST(eina_cxx_ptrarray_push_back)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> array;
array.push_back(new int(5));
array.push_back(new int(10));
array.push_back(new int(15));
int result[] = {5, 10, 15};
ck_assert(array.size() == 3);
ck_assert(std::equal(array.begin(), array.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrarray_pop_back)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> array;
array.push_back(new int(5));
array.push_back(new int(10));
array.push_back(new int(15));
array.pop_back();
int result[] = {5, 10};
ck_assert(array.size() == 2);
ck_assert(std::equal(array.begin(), array.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrarray_insert)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> array;
ck_assert(std::distance(array.begin(), array.end()) == 0u);
efl::eina::ptr_array<int>::iterator it;
it = array.insert(array.end(), new int(5)); // first element
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
ck_assert(array[0] == 5);
ck_assert(std::distance(array.begin(), array.end()) == 1u);
it = array.insert(array.end(), new int(10)); // equivalent to push_back
ck_assert(it != array.end());
++it;
ck_assert(it == array.end());
ck_assert(array[0] == 5);
ck_assert(array[1] == 10);
ck_assert(std::distance(array.begin(), array.end()) == 2u);
it = array.insert(array.begin(), new int(15)); // equivalent to push_front
ck_assert(it == array.begin());
ck_assert(array[1] == 5);
ck_assert(array[2] == 10);
ck_assert(array[0] == 15);
ck_assert(std::distance(array.begin(), array.end()) == 3u);
array.insert(array.end() - 1, new int(20)); // insert before the last element
ck_assert(array[0] == 15);
ck_assert(array[1] == 5);
ck_assert(array[2] == 20);
ck_assert(array[3] == 10);
ck_assert(std::distance(array.begin(), array.end()) == 4u);
int result[] = {15, 5, 20, 10};
ck_assert(array.size() == 4);
ck_assert(std::distance(array.begin(), array.end()) == 4u);
ck_assert(std::equal(array.begin(), array.end(), result));
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array2;
it = array2.insert(array2.end(), array.begin(), array.end());
ck_assert(it == array2.begin());
ck_assert(array == array2);
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array3;
array3.push_back(1);
it = array3.insert(array3.end(), array.begin(), array.end());
ck_assert(array3.size() == 5);
ck_assert(array3.front() == 1);
it = array3.begin();
++it;
ck_assert(std::equal(it, array3.end(), array.begin()));
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array4;
array4.push_back(1);
it = array4.insert(array4.begin(), array.begin(), array.end());
ck_assert(array4.size() == 5);
ck_assert(array4.back() == 1);
ck_assert(std::equal(array.begin(), array.end(), array4.begin()));
}
END_TEST
START_TEST(eina_cxx_ptrarray_constructors)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> array1;
ck_assert(array1.empty());
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array2(10, 5);
ck_assert(array2.size() == 10);
ck_assert(std::find_if(array2.begin(), array2.end()
, std::not1(std::bind1st(std::equal_to<int>(), 5))) == array2.end());
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array3(array2);
ck_assert(array2 == array3);
efl::eina::ptr_array<int, efl::eina::heap_copy_allocator> array4
(array2.begin(), array2.end());
ck_assert(array2 == array4);
}
END_TEST
START_TEST(eina_cxx_ptrarray_erase)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_array<int> array1;
array1.push_back(new int(5));
array1.push_back(new int(10));
array1.push_back(new int(15));
array1.push_back(new int(20));
array1.push_back(new int(25));
array1.push_back(new int(30));
int result[] = {5, 10, 15, 20, 25, 30};
ck_assert(std::equal(array1.begin(), array1.end(), result));
efl::eina::ptr_array<int>::iterator it = array1.erase(array1.begin());
ck_assert(it == array1.begin());
ck_assert(array1.size() == 5);
ck_assert(array1.front() == 10);
ck_assert(std::equal(array1.begin(), array1.end(), &result[1]));
it = array1.erase(array1.begin() + 1);
ck_assert(*it == 20);
ck_assert(array1.size() == 4);
it = array1.erase(array1.end() - 1);
ck_assert(it == array1.end());
ck_assert(array1.size() == 3);
ck_assert(array1.back() == 25);
it = array1.erase(array1.begin() + 1, array1.end() - 1);
ck_assert(it == array1.end() - 1);
ck_assert(array1.size() == 2);
ck_assert(array1.front() == 10);
ck_assert(array1.back() == 25);
}
END_TEST
void
eina_test_ptrarray(TCase* tc)
{
tcase_add_test(tc, eina_cxx_ptrarray_push_back);
tcase_add_test(tc, eina_cxx_ptrarray_pop_back);
tcase_add_test(tc, eina_cxx_ptrarray_insert);
tcase_add_test(tc, eina_cxx_ptrarray_constructors);
tcase_add_test(tc, eina_cxx_ptrarray_erase);
}

View File

@ -0,0 +1,212 @@
#include "Eina.hh"
#include <algorithm>
#include <check.h>
START_TEST(eina_cxx_ptrlist_push_back)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
int result[] = {5, 10, 15};
ck_assert(list.size() == 3);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrlist_pop_back)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
list.push_back(new int(5));
list.push_back(new int(10));
list.push_back(new int(15));
list.pop_back();
int result[] = {5, 10};
ck_assert(list.size() == 2);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrlist_push_front)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
list.push_front(new int(5));
list.push_front(new int(10));
list.push_front(new int(15));
int result[] = {15, 10, 5};
ck_assert(list.size() == 3);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrlist_pop_front)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
list.push_front(new int(5));
list.push_front(new int(10));
list.push_front(new int(15));
list.pop_front();
int result[] = {10, 5};
ck_assert(list.size() == 2);
ck_assert(std::equal(list.begin(), list.end(), result));
}
END_TEST
START_TEST(eina_cxx_ptrlist_insert)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list;
efl::eina::ptr_list<int>::iterator it;
it = list.insert(list.end(), new int(5)); // first element
ck_assert(it != list.end());
++it;
ck_assert(it == list.end());
it = list.insert(list.end(), new int(10)); // equivalent to push_back
ck_assert(it != list.end());
++it;
ck_assert(it == list.end());
it = list.insert(list.begin(), new int(15)); // equivalent to push_front
ck_assert(it == list.begin());
it = list.end();
--it;
list.insert(it, new int(20)); // insert before the last element
int result[] = {15, 5, 20, 10};
ck_assert(list.size() == 4);
ck_assert(std::equal(list.begin(), list.end(), result));
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list2;
it = list2.insert(list2.end(), list.begin(), list.end());
ck_assert(it == list2.begin());
ck_assert(list == list2);
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list3;
list3.push_back(1);
it = list3.insert(list3.end(), list.begin(), list.end());
ck_assert(list3.size() == 5);
ck_assert(list3.front() == 1);
it = list3.begin();
++it;
ck_assert(std::equal(it, list3.end(), list.begin()));
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list4;
list4.push_back(1);
it = list4.insert(list4.begin(), list.begin(), list.end());
ck_assert(list4.size() == 5);
ck_assert(list4.back() == 1);
ck_assert(std::equal(list.begin(), list.end(), list4.begin()));
}
END_TEST
START_TEST(eina_cxx_ptrlist_constructors)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list1;
ck_assert(list1.empty());
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list2(10, 5);
ck_assert(list2.size() == 10);
ck_assert(std::find_if(list2.begin(), list2.end()
, std::not1(std::bind1st(std::equal_to<int>(), 5))) == list2.end());
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list3(list2);
ck_assert(list2 == list3);
efl::eina::ptr_list<int, efl::eina::heap_copy_allocator> list4
(list2.begin(), list2.end());
ck_assert(list2 == list4);
}
END_TEST
START_TEST(eina_cxx_ptrlist_erase)
{
efl::eina::eina_init eina_init;
efl::eina::ptr_list<int> list1;
list1.push_back(new int(5));
list1.push_back(new int(10));
list1.push_back(new int(15));
list1.push_back(new int(20));
list1.push_back(new int(25));
list1.push_back(new int(30));
efl::eina::ptr_list<int>::iterator it = list1.begin(), it2;
it = list1.erase(it);
ck_assert(it == list1.begin());
ck_assert(list1.size() == 5);
ck_assert(list1.front() == 10);
it = list1.begin();
it2 = list1.begin();
++it;
++it2; ++it2;
ck_assert(*it2 == 20);
it = list1.erase(it);
ck_assert(it == it2);
ck_assert(list1.size() == 4);
ck_assert(*it2 == 20);
it = list1.end();
--it;
it = list1.erase(it);
ck_assert(it == list1.end());
ck_assert(list1.size() == 3);
ck_assert(list1.back() == 25);
it = list1.begin();
++it;
it2 = list1.end();
--it2;
it = list1.erase(it, it2);
it2 = list1.end();
--it2;
ck_assert(it == it2);
ck_assert(list1.size() == 2);
ck_assert(list1.front() == 10);
ck_assert(list1.back() == 25);
}
END_TEST
void
eina_test_ptrlist(TCase* tc)
{
tcase_add_test(tc, eina_cxx_ptrlist_push_back);
tcase_add_test(tc, eina_cxx_ptrlist_pop_back);
tcase_add_test(tc, eina_cxx_ptrlist_push_front);
tcase_add_test(tc, eina_cxx_ptrlist_pop_front);
tcase_add_test(tc, eina_cxx_ptrlist_insert);
tcase_add_test(tc, eina_cxx_ptrlist_constructors);
tcase_add_test(tc, eina_cxx_ptrlist_erase);
}

View File

@ -0,0 +1,32 @@
#include "Eina.hh"
#include <algorithm>
#include <functional>
#include <check.h>
START_TEST(eina_cxx_stringshare_constructors)
{
efl::eina::eina_init eina_init;
efl::eina::stringshare string1;
ck_assert(string1.empty());
efl::eina::stringshare string2("string");
ck_assert(string2.size() == 6);
ck_assert(string2 == "string");
efl::eina::stringshare string3(string2);
ck_assert(string2 == string3);
efl::eina::stringshare string4(string3.begin(), string3.end());
ck_assert(string2 == string3);
}
END_TEST
void
eina_test_stringshare(TCase *tc)
{
tcase_add_test(tc, eina_cxx_stringshare_constructors);
}

View File

@ -0,0 +1,127 @@
#include "Eina.hh"
#include <algorithm>
#include <check.h>
bool no_args = false
, args_1 = false
, args_2 = false;
void thread_no_args()
{
no_args = true;
}
struct test
{
int x;
};
void thread_1_arg(int a0)
{
args_1 = true;
ck_assert(a0 == 5);
}
void thread_2_arg(int a0, test t)
{
args_2 = true;
ck_assert(a0 == 5);
ck_assert(t.x == 10);
}
START_TEST(eina_cxx_thread_constructors)
{
efl::eina::eina_init init;
efl::eina::eina_threads_init threads_init;
{
efl::eina::thread default_constructed_thread;
ck_assert(default_constructed_thread.get_id() == efl::eina::thread::id());
}
{
efl::eina::thread thread_no_args(&::thread_no_args);
thread_no_args.join();
ck_assert( ::no_args);
}
{
efl::eina::thread thread_1_arg(&::thread_1_arg, 5);
thread_1_arg.join();
ck_assert( ::args_1);
}
{
test t = {10};
efl::eina::thread thread_2_arg(&::thread_2_arg, 5, t);
thread_2_arg.join();
ck_assert( ::args_2);
}
}
END_TEST
START_TEST(eina_cxx_thread_mutexes)
{
efl::eina::mutex m;
{
efl::eina::unique_lock<efl::eina::mutex> lock1(m);
ck_assert(lock1.owns_lock());
lock1.unlock();
ck_assert(!lock1.owns_lock());
ck_assert(lock1.try_lock());
ck_assert(lock1.owns_lock());
lock1.unlock();
lock1.lock();
ck_assert(lock1.owns_lock());
}
{
efl::eina::lock_guard<efl::eina::mutex> lock1(m);
}
}
END_TEST
bool b = false;
void condition_thread(efl::eina::mutex& condition_mutex
, efl::eina::condition_variable& condition_condition)
{
efl::eina::unique_lock<efl::eina::mutex> l( condition_mutex);
b = true;
condition_condition.notify_one();
}
START_TEST(eina_cxx_thread_conditional)
{
efl::eina::mutex m;
efl::eina::mutex condition_mutex;
efl::eina::condition_variable condition_condition;
efl::eina::unique_lock<efl::eina::mutex> l( condition_mutex);
efl::eina::thread thread(&condition_thread, std::ref(condition_mutex), std::ref(condition_condition));
while(!b)
{
ck_assert(l.owns_lock());
condition_condition.wait(l);
ck_assert(l.owns_lock());
}
thread.join();
}
END_TEST
void
eina_test_thread(TCase* tc)
{
tcase_add_test(tc, eina_cxx_thread_constructors);
tcase_add_test(tc, eina_cxx_thread_mutexes);
tcase_add_test(tc, eina_cxx_thread_conditional);
}