forked from enlightenment/efl
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:
parent
d63507446f
commit
f279225a63
|
@ -119,6 +119,7 @@ endif
|
|||
|
||||
pkgconfig_DATA += \
|
||||
pc/eina.pc \
|
||||
pc/eina-cxx.pc \
|
||||
pc/eo.pc \
|
||||
pc/eet.pc \
|
||||
pc/evas.pc \
|
||||
|
|
18
configure.ac
18
configure.ac
|
@ -890,6 +890,21 @@ EFL_LIB_END([Eina])
|
|||
#### End of Eina
|
||||
|
||||
|
||||
#### Eina CXX
|
||||
EFL_LIB_START([Eina_Cxx])
|
||||
|
||||
AX_CXX_COMPILE_STDCXX_11([ext])
|
||||
if test "x${HAVE_CXX11}" -a "x1"; then
|
||||
have_cxx11="yes"
|
||||
else
|
||||
have_cxx11="no"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([HAVE_CXX11], [test "x${have_cxx11}" -a "xyes"])
|
||||
|
||||
EFL_LIB_END([Eina_Cxx])
|
||||
#### End of Eina CXX
|
||||
|
||||
#### Eet
|
||||
|
||||
EFL_LIB_START([Eet])
|
||||
|
@ -3927,6 +3942,7 @@ src/Makefile
|
|||
src/benchmarks/eina/Makefile
|
||||
src/benchmarks/eo/Makefile
|
||||
src/examples/eina/Makefile
|
||||
src/examples/eina_cxx/Makefile
|
||||
src/examples/eet/Makefile
|
||||
src/examples/eo/Makefile
|
||||
src/examples/evas/Makefile
|
||||
|
@ -3945,6 +3961,7 @@ spec/efl.spec
|
|||
pc/evil.pc
|
||||
pc/escape.pc
|
||||
pc/eina.pc
|
||||
pc/eina-cxx.pc
|
||||
pc/eet.pc
|
||||
pc/eo.pc
|
||||
pc/evas-fb.pc
|
||||
|
@ -4075,6 +4092,7 @@ echo " Threads.......: ${efl_have_threads} (${features_thread})"
|
|||
echo " Cryptography..: ${build_crypto}"
|
||||
echo " X11...........: ${with_x11}"
|
||||
echo " OpenGL........: ${with_opengl}"
|
||||
echo " C++11.........: ${have_cxx11}"
|
||||
echo "Evas............: yes (${features_evas})"
|
||||
echo " Engines.......: ${features_evas_engine}"
|
||||
echo " Image Loaders.: ${features_evas_loader}"
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
# ============================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
|
||||
# ============================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the C++11
|
||||
# standard; if necessary, add switches to CXXFLAGS to enable support.
|
||||
#
|
||||
# The first argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The second argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline C++11 support is required and that the macro
|
||||
# should error out if no mode with that support is found. If specified
|
||||
# 'optional', then configuration proceeds regardless, after defining
|
||||
# HAVE_CXX11 if and only if a supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 3
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
typedef check<check<bool>> right_angle_brackets;
|
||||
|
||||
int a;
|
||||
decltype(a) b;
|
||||
|
||||
typedef check<int> check_type;
|
||||
check_type c;
|
||||
check_type&& cr = static_cast<check_type&&>(c);
|
||||
|
||||
auto d = a;
|
||||
])
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
|
||||
m4_if([$1], [], [],
|
||||
[$1], [ext], [],
|
||||
[$1], [noext], [],
|
||||
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
|
||||
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||
ax_cv_cxx_compile_cxx11,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[ax_cv_cxx_compile_cxx11=yes],
|
||||
[ax_cv_cxx_compile_cxx11=no])])
|
||||
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||
ac_success=yes
|
||||
fi
|
||||
|
||||
m4_if([$1], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=gnu++11 -std=gnu++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$1], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for switch in -std=c++11 -std=c++0x; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXXFLAGS="$CXXFLAGS $switch"
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx11_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
|
||||
fi
|
||||
else
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX11=0
|
||||
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||
else
|
||||
HAVE_CXX11=1
|
||||
AC_DEFINE(HAVE_CXX11,1,
|
||||
[define if the compiler supports basic C++11 syntax])
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_CXX11)
|
||||
fi
|
||||
])
|
|
@ -24,6 +24,7 @@
|
|||
/efreet-trash.pc
|
||||
/efreet.pc
|
||||
/eina.pc
|
||||
/eina-cxx.pc
|
||||
/eio.pc
|
||||
/eldbus.pc
|
||||
/embryo.pc
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Eina C++
|
||||
Description: A C++ binding for the Eina library
|
||||
Requires.private: @requirements_pc_eina@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -leina @requirements_public_libs_eina@
|
||||
Libs.private: @requirements_libs_eina@
|
||||
Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eina-@VMAJ@ -I${includedir}/eina-@VMAJ@/eina -I${includedir}/eina_cxx-@VMAJ@ -I${includedir}/eina_cxx-@VMAJ@/eina_cxx
|
|
@ -56,6 +56,8 @@ include Makefile_Emotion.am
|
|||
include Makefile_Ethumb.am
|
||||
include Makefile_Ethumb_Client.am
|
||||
|
||||
include Makefile_Eina_Cxx.am
|
||||
|
||||
.PHONY: benchmark examples
|
||||
|
||||
BENCHMARK_SUBDIRS = \
|
||||
|
@ -71,6 +73,7 @@ benchmark: all-am
|
|||
|
||||
EXAMPLES_SUBDIRS = \
|
||||
examples/eina \
|
||||
examples/eina_cxx \
|
||||
examples/eo \
|
||||
examples/eet \
|
||||
examples/evas \
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
### Library
|
||||
|
||||
#lib_LTLIBRARIES += lib/eina/libeina.la
|
||||
|
||||
installed_einacxxmainheadersdir = $(includedir)/eina_cxx-@VMAJ@
|
||||
dist_installed_einacxxmainheaders_DATA = \
|
||||
lib/eina_cxx/Eina.hh
|
||||
|
||||
installed_einacxxheadersdir = $(includedir)/eina_cxx-@VMAJ@/eina_cxx
|
||||
dist_installed_einacxxheaders_DATA = \
|
||||
lib/eina_cxx/eina_accessor.hh \
|
||||
lib/eina_cxx/eina_clone_allocators.hh \
|
||||
lib/eina_cxx/eina_error.hh \
|
||||
lib/eina_cxx/eina_inarray.hh \
|
||||
lib/eina_cxx/eina_inlist.hh \
|
||||
lib/eina_cxx/eina_iterator.hh \
|
||||
lib/eina_cxx/eina_lists_auxiliary.hh \
|
||||
lib/eina_cxx/eina_ptrarray.hh \
|
||||
lib/eina_cxx/eina_ptrlist.hh \
|
||||
lib/eina_cxx/eina_ref.hh \
|
||||
lib/eina_cxx/eina_stringshare.hh \
|
||||
lib/eina_cxx/eina_thread.hh \
|
||||
lib/eina_cxx/eina_type_traits.hh \
|
||||
lib/eina_cxx/eina_value.hh
|
||||
|
||||
### Unit tests
|
||||
|
||||
if EFL_ENABLE_TESTS
|
||||
if HAVE_CXX11
|
||||
|
||||
check_PROGRAMS += tests/eina_cxx/eina_cxx_suite
|
||||
TESTS += tests/eina_cxx/eina_cxx_suite
|
||||
|
||||
tests_eina_cxx_eina_cxx_suite_SOURCES = \
|
||||
tests/eina_cxx/eina_cxx_suite.cc \
|
||||
tests/eina_cxx/eina_cxx_test_inlist.cc \
|
||||
tests/eina_cxx/eina_cxx_test_inarray.cc \
|
||||
tests/eina_cxx/eina_cxx_test_iterator.cc \
|
||||
tests/eina_cxx/eina_cxx_test_ptrarray.cc \
|
||||
tests/eina_cxx/eina_cxx_test_ptrlist.cc \
|
||||
tests/eina_cxx/eina_cxx_test_stringshare.cc \
|
||||
tests/eina_cxx/eina_cxx_test_error.cc \
|
||||
tests/eina_cxx/eina_cxx_test_accessor.cc \
|
||||
tests/eina_cxx/eina_cxx_test_thread.cc \
|
||||
tests/eina_cxx/eina_cxx_test_eina_value.cc
|
||||
|
||||
tests_eina_cxx_eina_cxx_suite_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_builddir)/src/lib/eina_cxx \
|
||||
-DTESTS_WD=\"`pwd`\" \
|
||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eina_cxx\" \
|
||||
-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/src/tests/eina_cxx\" \
|
||||
-DTESTS_BUILD_DIR=PACKAGE_BUILD_DIR \
|
||||
@CHECK_CFLAGS@ \
|
||||
@EINA_CFLAGS@
|
||||
tests_eina_cxx_eina_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EINA_LIBS@
|
||||
tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
|
||||
|
||||
endif
|
||||
endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_builddir)/src/lib/efl \
|
||||
-I. \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/lib/eina_cxx \
|
||||
-I$(top_builddir)/src/lib/eina_cxx
|
||||
|
||||
LDADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LDFLAGS@ @USE_BOOST_SYSTEM_LIBS@ @USE_BOOST_SYSTEM_LDFLAGS@
|
||||
AM_CXXFLAGS = @USE_BOOST_CPPFLAGS@
|
||||
|
||||
SRCS = \
|
||||
eina_cxx_list_01.cc
|
||||
|
||||
EXTRA_PROGRAMS = \
|
||||
eina_cxx_list_01 \
|
||||
eina_cxx_thread_01
|
||||
|
||||
eina_cxx_list_01_SOURCES = \
|
||||
eina_cxx_list_01.cc
|
||||
|
||||
eina_cxx_thread_01_SOURCES = \
|
||||
eina_cxx_thread_01.cc
|
||||
|
||||
EXTRA_DIST = $(DATA_FILES)
|
||||
|
||||
examples: $(EXTRA_PROGRAMS)
|
||||
|
||||
clean-local:
|
||||
rm -f $(EXTRA_PROGRAMS)
|
||||
|
||||
install-examples:
|
||||
mkdir -p $(datadir)/eina/examples
|
||||
$(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eina/examples
|
||||
|
||||
uninstall-local:
|
||||
for f in $(SRCS) $(DATA_FILES); do \
|
||||
rm -f $(datadir)/eina/examples/$$f ; \
|
||||
done
|
||||
|
||||
if ALWAYS_BUILD_EXAMPLES
|
||||
noinst_PROGRAMS = $(EXTRA_PROGRAMS)
|
||||
endif
|
|
@ -0,0 +1,55 @@
|
|||
//Compile with:
|
||||
//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Eina.hh>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <typename I>
|
||||
I next(I i, std::size_t n = 1u)
|
||||
{
|
||||
for(;n;--n)
|
||||
++i;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
|
||||
efl::eina::ptr_list<std::string, efl::eina::heap_copy_allocator> list;
|
||||
|
||||
list.push_back("tigh");
|
||||
list.push_back("adar");
|
||||
list.push_back("baltar");
|
||||
list.push_back("roslin");
|
||||
|
||||
for(efl::eina::ptr_list<std::string>::const_iterator
|
||||
first = list.begin(), last = list.end()
|
||||
;first != last; ++first)
|
||||
std::cout << *first << std::endl;
|
||||
|
||||
efl::eina::ptr_list<std::string>::iterator
|
||||
iterator = ::next(list.begin(), 2u);
|
||||
list.insert(iterator, "cain");
|
||||
|
||||
iterator = std::find(list.begin(), list.end(), "cain");
|
||||
assert(iterator != list.end() && ::next(iterator) != list.end());
|
||||
list.insert(::next(iterator), "zarek");
|
||||
|
||||
list.insert(list.begin(), "adama");
|
||||
|
||||
iterator = std::find(list.begin(), list.end(), "cain");
|
||||
assert(iterator != list.end());
|
||||
list.insert(iterator, "gaeta");
|
||||
|
||||
list.insert(::next(list.begin()), "lampkin");
|
||||
|
||||
for(efl::eina::ptr_list<std::string>::const_iterator
|
||||
first = list.begin(), last = list.end()
|
||||
;first != last; ++first)
|
||||
std::cout << *first << std::endl;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//Compile with:
|
||||
//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Eina.hh>
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace eina = efl::eina;
|
||||
|
||||
void thread1(eina::mutex& m)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
eina::eina_init eina_init;
|
||||
eina::eina_threads_init threads_init;
|
||||
|
||||
eina::mutex m;
|
||||
eina::condition_variable c;
|
||||
|
||||
eina::unique_lock<eina::mutex> l(m);
|
||||
|
||||
eina::thread thread1(&::thread1, eina::ref(m));
|
||||
|
||||
thread1.join();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef EINA_HH_
|
||||
#define EINA_HH_
|
||||
|
||||
#include <eina_iterator.hh>
|
||||
#include <eina_ptrarray.hh>
|
||||
#include <eina_ptrlist.hh>
|
||||
#include <eina_inarray.hh>
|
||||
#include <eina_inlist.hh>
|
||||
#include <eina_stringshare.hh>
|
||||
#include <eina_error.hh>
|
||||
#include <eina_accessor.hh>
|
||||
#include <eina_thread.hh>
|
||||
#include <eina_value.hh>
|
||||
#include <eina_ref.hh>
|
||||
|
||||
namespace efl { namespace eina {
|
||||
|
||||
struct eina_init
|
||||
{
|
||||
eina_init()
|
||||
{
|
||||
::eina_init();
|
||||
}
|
||||
~eina_init()
|
||||
{
|
||||
::eina_shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
struct eina_threads_init
|
||||
{
|
||||
eina_threads_init()
|
||||
{
|
||||
::eina_threads_init();
|
||||
}
|
||||
~eina_threads_init()
|
||||
{
|
||||
::eina_threads_shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,214 @@
|
|||
#ifndef EINA_ACCESSOR_HH_
|
||||
#define EINA_ACCESSOR_HH_
|
||||
|
||||
#include <Eina.h>
|
||||
#include <eina_error.hh>
|
||||
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
namespace efl { namespace eina {
|
||||
|
||||
template <typename T>
|
||||
struct accessor
|
||||
{
|
||||
typedef unsigned int key_type;
|
||||
typedef T mapped_type;
|
||||
typedef T value_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
accessor() : _impl(0) {}
|
||||
explicit accessor(Eina_Accessor* impl)
|
||||
: _impl(impl)
|
||||
{
|
||||
assert(_impl != 0);
|
||||
}
|
||||
accessor(accessor<T> const& other)
|
||||
: _impl(eina_accessor_clone(other._impl))
|
||||
{}
|
||||
accessor<T>& operator=(accessor<T> const& other)
|
||||
{
|
||||
eina_accessor_free(_impl);
|
||||
_impl = eina_accessor_clone(other._impl);
|
||||
if(!_impl)
|
||||
throw eina::system_error(efl::eina::get_error_code(), "Error cloning accessor");
|
||||
return *this;
|
||||
}
|
||||
~accessor()
|
||||
{
|
||||
eina_accessor_free(_impl);
|
||||
}
|
||||
|
||||
mapped_type& operator[](size_type i) const
|
||||
{
|
||||
assert(_impl != 0);
|
||||
void* p;
|
||||
if(!eina_accessor_data_get(_impl, i, &p))
|
||||
{
|
||||
eina::error_code ec = efl::eina::get_error_code();
|
||||
throw eina::system_error(ec, "EFL Eina Error");
|
||||
}
|
||||
return *static_cast<mapped_type*>(p);
|
||||
}
|
||||
|
||||
Eina_Accessor* native_handle() const;
|
||||
|
||||
void swap(accessor<T>& other)
|
||||
{
|
||||
std::swap(_impl, other._impl);
|
||||
}
|
||||
private:
|
||||
typedef Eina_Accessor*(accessor<T>::*unspecified_bool_type)() const;
|
||||
public:
|
||||
operator unspecified_bool_type() const
|
||||
{
|
||||
return native_handle() ? &accessor<T>::native_handle : 0 ;
|
||||
}
|
||||
private:
|
||||
Eina_Accessor* _impl;
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
void swap(accessor<U>& lhs, accessor<U>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct accessor_iterator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
|
||||
accessor_iterator(accessor<T> const& a, unsigned int pos = 0u)
|
||||
: _accessor(a), _index(pos)
|
||||
{}
|
||||
|
||||
accessor_iterator<T>& operator+=(difference_type i)
|
||||
{
|
||||
_index += i;
|
||||
return *this;
|
||||
}
|
||||
accessor_iterator<T>& operator-=(difference_type i)
|
||||
{
|
||||
_index -= i;
|
||||
return *this;
|
||||
}
|
||||
value_type& operator[](difference_type i)
|
||||
{
|
||||
return _accessor[_index + i];
|
||||
}
|
||||
accessor_iterator<T>& operator++()
|
||||
{
|
||||
++_index;
|
||||
return *this;
|
||||
}
|
||||
accessor_iterator<T>& operator--()
|
||||
{
|
||||
--_index;
|
||||
return *this;
|
||||
}
|
||||
accessor_iterator<T>& operator++(int)
|
||||
{
|
||||
accessor_iterator<T> tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
accessor_iterator<T>& operator--(int)
|
||||
{
|
||||
accessor_iterator<T> tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
value_type& operator*() const
|
||||
{
|
||||
return _accessor[_index];
|
||||
}
|
||||
pointer operator->() const
|
||||
{
|
||||
return &**this;
|
||||
}
|
||||
void swap(accessor_iterator<T>& other)
|
||||
{
|
||||
std::swap(_index, other._index);
|
||||
std::swap(_accessor, other._accessor);
|
||||
}
|
||||
private:
|
||||
accessor<T> _accessor;
|
||||
unsigned int _index;
|
||||
|
||||
template <typename U>
|
||||
friend bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index == rhs._index;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend typename accessor_iterator<U>::difference_type
|
||||
operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index - rhs._index;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend
|
||||
accessor_iterator<U> operator+(accessor_iterator<U> lhs
|
||||
, typename accessor_iterator<U>::difference_type rhs)
|
||||
{
|
||||
lhs._index += rhs;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend
|
||||
accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
|
||||
, accessor_iterator<U> rhs)
|
||||
{
|
||||
return rhs + lhs;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index < rhs._index;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
friend bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return lhs._index <= rhs._index;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(lhs <= rhs);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator!=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void swap(accessor_iterator<U>& lhs, accessor_iterator<U>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef EINA_CLONE_ALLOCATORS_HH_
|
||||
#define EINA_CLONE_ALLOCATORS_HH_
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace efl { namespace eina {
|
||||
|
||||
struct heap_copy_allocator
|
||||
{
|
||||
template <typename T>
|
||||
static T* allocate_clone(T const& v)
|
||||
{
|
||||
return new T(v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void deallocate_clone(T* p)
|
||||
{
|
||||
#ifdef EFL_EINA_CXX11
|
||||
std::default_delete<T>()(p);
|
||||
#else
|
||||
delete p;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct heap_clone_allocator
|
||||
{
|
||||
template <typename T>
|
||||
static T* allocate_clone(T const& v)
|
||||
{
|
||||
return new_clone(v);
|
||||
}
|
||||
template <typename T>
|
||||
static void deallocate_clone(T* p)
|
||||
{
|
||||
delete_clone(p);
|
||||
}
|
||||
};
|
||||
|
||||
struct view_clone_allocator
|
||||
{
|
||||
template <typename T>
|
||||
static T* allocate_clone(T const& v)
|
||||
{
|
||||
return const_cast<T*>(&v);
|
||||
}
|
||||
template <typename T>
|
||||
static void deallocate_clone(T* p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct heap_no_copy_allocator
|
||||
{
|
||||
template <typename T>
|
||||
static void deallocate_clone(T* p)
|
||||
{
|
||||
#ifdef EFL_EINA_CXX11
|
||||
std::default_delete<T>()(p);
|
||||
#else
|
||||
delete p;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef _EINA_ERROR_HH
|
||||
#define _EINA_ERROR_HH
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include <system_error>
|
||||
|
||||
namespace efl { namespace eina {
|
||||
|
||||
using std::errc;
|
||||
using std::system_error;
|
||||
using std::error_code;
|
||||
using std::error_condition;
|
||||
typedef std::error_category system_error_category;
|
||||
|
||||
inline system_error_category const& get_generic_category()
|
||||
{
|
||||
return ::std::generic_category();
|
||||
}
|
||||
inline system_error_category const& get_system_category()
|
||||
{
|
||||
return ::std::system_category();
|
||||
}
|
||||
|
||||
enum error_type {};
|
||||
|
||||
struct error_category : system_error_category
|
||||
{
|
||||
const char* name() const throw()
|
||||
{
|
||||
return "eina";
|
||||
}
|
||||
|
||||
bool equivalent(int code, eina::error_condition const& condition) const throw()
|
||||
{
|
||||
return code == condition.value();
|
||||
}
|
||||
|
||||
bool equivalent(eina::error_code const& code, int condition) const throw()
|
||||
{
|
||||
return code.value() == condition;
|
||||
}
|
||||
|
||||
std::string message(int condition) const
|
||||
{
|
||||
const char* e = ::eina_error_msg_get(condition);
|
||||
return e? e : "::eina_error_msg_get returned NULL. No error message available";
|
||||
}
|
||||
};
|
||||
|
||||
inline eina::system_error_category& eina_error_category()
|
||||
{
|
||||
static error_category _error_category;
|
||||
return _error_category;
|
||||
}
|
||||
|
||||
inline eina::error_code get_error_code()
|
||||
{
|
||||
Eina_Error error = eina_error_get();
|
||||
if(error)
|
||||
{
|
||||
eina_error_set(0);
|
||||
return eina::error_code(error, eina_error_category());
|
||||
}
|
||||
else
|
||||
return eina::error_code();
|
||||
}
|
||||
|
||||
inline eina::error_condition get_error_condition()
|
||||
{
|
||||
Eina_Error error = eina_error_get();
|
||||
if(error)
|
||||
{
|
||||
eina_error_set(0);
|
||||
return eina::error_condition(error, eina_error_category());
|
||||
}
|
||||
else
|
||||
return eina::error_condition();
|
||||
}
|
||||
|
||||
inline error_type get_error_code_enum()
|
||||
{
|
||||
return static_cast<error_type>( ::eina_error_get() );
|
||||
}
|
||||
|
||||
|
||||
inline void throw_on_error()
|
||||
{
|
||||
eina::error_code ec = get_error_code();
|
||||
if(ec)
|
||||
{
|
||||
throw eina::system_error(ec, "EFL Eina Error");
|
||||
}
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
namespace std {
|
||||
|
||||
template <> struct is_error_condition_enum< ::efl::eina::error_type> : true_type {};
|
||||
template <> struct is_error_code_enum< ::efl::eina::error_type> : true_type {};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,544 @@
|
|||
#ifndef EINA_INARRAY_HH_
|
||||
#define EINA_INARRAY_HH_
|
||||
|
||||
#include <Eina.h>
|
||||
#include <eina_type_traits.hh>
|
||||
|
||||
#include <iterator>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
namespace efl { namespace eina {
|
||||
|
||||
struct _inarray_common_base
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
|
||||
explicit _inarray_common_base(size_type member_size)
|
||||
: _array( ::eina_inarray_new(member_size, 0) )
|
||||
{
|
||||
}
|
||||
~_inarray_common_base()
|
||||
{
|
||||
::eina_inarray_free(_array);
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return ::eina_inarray_count(_array);
|
||||
}
|
||||
bool empty() const
|
||||
{
|
||||
return size() == 0u;
|
||||
}
|
||||
|
||||
Eina_Inarray* _array;
|
||||
private:
|
||||
_inarray_common_base(_inarray_common_base const& other);
|
||||
_inarray_common_base& operator=(_inarray_common_base const& other);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class _pod_inarray : _inarray_common_base
|
||||
{
|
||||
typedef _inarray_common_base _base_type;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
using _base_type::size;
|
||||
using _base_type::empty;
|
||||
|
||||
_pod_inarray() : _base_type(sizeof(T))
|
||||
{
|
||||
}
|
||||
_pod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
|
||||
{
|
||||
while(n--)
|
||||
push_back(t);
|
||||
}
|
||||
template <typename InputIterator>
|
||||
_pod_inarray(InputIterator i, InputIterator const& j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
|
||||
: _base_type(sizeof(T))
|
||||
{
|
||||
while(i != j)
|
||||
{
|
||||
push_back(*i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
_pod_inarray(_pod_inarray<T>const& other)
|
||||
: _base_type(sizeof(T))
|
||||
{
|
||||
insert(end(), other.begin(), other.end());
|
||||
}
|
||||
~_pod_inarray()
|
||||
{
|
||||
}
|
||||
_pod_inarray<T>& operator=(_pod_inarray<T>const& other)
|
||||
{
|
||||
clear();
|
||||
insert(end(), other.begin(), other.end());
|
||||
return *this;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
::eina_inarray_flush(_array);
|
||||
}
|
||||
void push_back(T const& value)
|
||||
{
|
||||
eina_inarray_push(_array, &value);
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
eina_inarray_pop(_array);
|
||||
}
|
||||
iterator insert(iterator i, value_type const& t)
|
||||
{
|
||||
if(i != end())
|
||||
{
|
||||
T* q = static_cast<iterator>
|
||||
( ::eina_inarray_alloc_at(_array, i - begin(), 1u));
|
||||
std::memcpy(q, &t, sizeof(t));
|
||||
return q;
|
||||
}
|
||||
else
|
||||
{
|
||||
push_back(t);
|
||||
return end()-1;
|
||||
}
|
||||
}
|
||||
iterator insert(iterator i, size_t n, value_type const& t)
|
||||
{
|
||||
T* q;
|
||||
if(i != end())
|
||||
{
|
||||
q = static_cast<iterator>
|
||||
( ::eina_inarray_alloc_at(_array, i - &_array->members, n));
|
||||
}
|
||||
else
|
||||
{
|
||||
q = eina_inarray_grow(_array, n);
|
||||
}
|
||||
for(T* p = q; n; --n, ++p)
|
||||
std::memcpy(p, &t, sizeof(t));
|
||||
return q;
|
||||
}
|
||||
template <typename InputIterator>
|
||||
iterator insert(iterator p, InputIterator i, InputIterator j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
|
||||
{
|
||||
size_type n = 0;
|
||||
while(i != j)
|
||||
{
|
||||
p = insert(p, *i);
|
||||
++p;
|
||||
++i;
|
||||
++n;
|
||||
}
|
||||
return p - n;
|
||||
}
|
||||
iterator erase(iterator q)
|
||||
{
|
||||
::eina_inarray_remove_at(_array, q - begin());
|
||||
return q;
|
||||
}
|
||||
iterator erase(iterator i, iterator j)
|
||||
{
|
||||
while(i != j)
|
||||
{
|
||||
erase(--j);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
template <typename InputIterator>
|
||||
void assign(InputIterator i, InputIterator j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
|
||||
void assign(size_type n, value_type const& t);
|
||||
value_type& back()
|
||||
{
|
||||
assert(!empty());
|
||||
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
|
||||
}
|
||||
value_type const& back() const
|
||||
{
|
||||
return const_cast<_pod_inarray<T>&>(*this).back();
|
||||
}
|
||||
value_type& front()
|
||||
{
|
||||
assert(!empty());
|
||||
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
|
||||
}
|
||||
value_type const& front() const
|
||||
{
|
||||
return const_cast<_pod_inarray<T>&>(*this).front();
|
||||
}
|
||||
iterator begin()
|
||||
{
|
||||
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, 0u));
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, size()-1)) + 1;
|
||||
}
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_cast< _pod_inarray<T>&>(*this).begin();
|
||||
}
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_cast< _pod_inarray<T>&>(*this).end();
|
||||
}
|
||||
const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const
|
||||
{
|
||||
return end();
|
||||
}
|
||||
const_reverse_iterator crbegin() const
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
void swap(_pod_inarray<T>& other)
|
||||
{
|
||||
std::swap(_array, other._array);
|
||||
}
|
||||
size_type max_size() const { return -1; }
|
||||
|
||||
Eina_Inarray* native_handle()
|
||||
{
|
||||
return this->_array;
|
||||
}
|
||||
Eina_Inarray const* native_handle() const
|
||||
{
|
||||
return this->_array;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class _nonpod_inarray : _inarray_common_base
|
||||
{
|
||||
typedef _inarray_common_base _base_type;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
using _base_type::size;
|
||||
using _base_type::empty;
|
||||
|
||||
_nonpod_inarray() : _base_type(sizeof(T))
|
||||
{
|
||||
}
|
||||
_nonpod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
|
||||
{
|
||||
while(n--)
|
||||
push_back(t);
|
||||
}
|
||||
template <typename InputIterator>
|
||||
_nonpod_inarray(InputIterator i, InputIterator const& j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
|
||||
: _base_type(sizeof(T))
|
||||
{
|
||||
while(i != j)
|
||||
{
|
||||
push_back(*i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
_nonpod_inarray(_nonpod_inarray<T>const& other)
|
||||
: _base_type(sizeof(T))
|
||||
{
|
||||
insert(end(), other.begin(), other.end());
|
||||
}
|
||||
~_nonpod_inarray()
|
||||
{
|
||||
for(T* first = static_cast<T*>(_array->members)
|
||||
, *last = first + _array->len; first != last; ++first)
|
||||
first->~T();
|
||||
}
|
||||
_nonpod_inarray<T>& operator=(_nonpod_inarray<T>const& other)
|
||||
{
|
||||
clear();
|
||||
insert(end(), other.begin(), other.end());
|
||||
return *this;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
for(T* first = static_cast<T*>(_array->members)
|
||||
, *last = first + _array->len; first != last; ++first)
|
||||
first->~T();
|
||||
::eina_inarray_flush(_array);
|
||||
}
|
||||
void push_back(T const& value)
|
||||
{
|
||||
insert(end(), 1u, value);
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
T* elem = static_cast<T*>(_array->members) + _array->len - 1;
|
||||
elem->~T();
|
||||
eina_inarray_pop(_array);
|
||||
}
|
||||
iterator insert(iterator i, value_type const& t)
|
||||
{
|
||||
return insert(i, 1u, t);
|
||||
}
|
||||
iterator insert(iterator i, size_t n, value_type const& t)
|
||||
{
|
||||
if(_array->max - _array->len >= n)
|
||||
{
|
||||
iterator end = static_cast<T*>(_array->members)
|
||||
+ _array->len
|
||||
, last = end + n;
|
||||
_array->len += n;
|
||||
std::reverse_iterator<iterator>
|
||||
dest(last), src(end), src_end(i);
|
||||
for(;src != src_end; ++src)
|
||||
{
|
||||
if(dest.base() <= end)
|
||||
*dest++ = *src;
|
||||
else
|
||||
new (&*dest++) T(*src);
|
||||
}
|
||||
iterator j = i;
|
||||
for(size_type i = 0;i != n;++i)
|
||||
{
|
||||
if(j < end)
|
||||
*j = t;
|
||||
else
|
||||
new (&*j++) T(t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_type index = i - static_cast<iterator>(_array->members);
|
||||
|
||||
Eina_Inarray* old_array = eina_inarray_new(_array->member_size, 0);
|
||||
*old_array = *_array;
|
||||
_array->len = _array->max = 0;
|
||||
_array->members = 0;
|
||||
eina_inarray_resize(_array, old_array->len+n);
|
||||
_array->len = old_array->len+n;
|
||||
|
||||
iterator old_first = static_cast<iterator>(old_array->members)
|
||||
, first = begin()
|
||||
, last = first + _array->len;
|
||||
i = index + begin();
|
||||
|
||||
while(first != i)
|
||||
{
|
||||
new (&*first++) T(*old_first);
|
||||
old_first++->~T();
|
||||
}
|
||||
for(size_type i = 0;i != n;++i)
|
||||
new (&*first++) T(t);
|
||||
assert(last - first == _array->len - index - n);
|
||||
while(first != last)
|
||||
{
|
||||
new (&*first++) T(*old_first);
|
||||
old_first++->~T();
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
template <typename InputIterator>
|
||||
iterator insert(iterator p, InputIterator i, InputIterator j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
|
||||
{
|
||||
size_type n = 0;
|
||||
while(i != j)
|
||||
{
|
||||
p = insert(p, *i);
|
||||
++p;
|
||||
++i;
|
||||
++n;
|
||||
}
|
||||
return p - n;
|
||||
}
|
||||
iterator erase(iterator q)
|
||||
{
|
||||
return erase(q, q+1);
|
||||
}
|
||||
iterator erase(iterator i, iterator j)
|
||||
{
|
||||
iterator last = end();
|
||||
iterator k = i, l = j;
|
||||
while(l != last)
|
||||
*k++ = *l++;
|
||||
while(k != last)
|
||||
k++->~T();
|
||||
_array->len -= j - i;
|
||||
|
||||
return i;
|
||||
}
|
||||
template <typename InputIterator>
|
||||
void assign(InputIterator i, InputIterator j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
|
||||
void assign(size_type n, value_type const& t);
|
||||
value_type& back()
|
||||
{
|
||||
assert(!empty());
|
||||
return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
|
||||
}
|
||||
value_type const& back() const
|
||||
{
|
||||
return const_cast<_nonpod_inarray<T>&>(*this).back();
|
||||
}
|
||||
value_type& front()
|
||||
{
|
||||
assert(!empty());
|
||||
return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
|
||||
}
|
||||
value_type const& front() const
|
||||
{
|
||||
return const_cast<_nonpod_inarray<T>&>(*this).front();
|
||||
}
|
||||
iterator begin()
|
||||
{
|
||||
return static_cast<iterator>(_array->members);
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
return static_cast<iterator>(_array->members) + _array->len;
|
||||
}
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_cast< _nonpod_inarray<T>&>(*this).begin();
|
||||
}
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_cast< _nonpod_inarray<T>&>(*this).end();
|
||||
}
|
||||
const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
const_iterator cend() const
|
||||
{
|
||||
return end();
|
||||
}
|
||||
const_reverse_iterator crbegin() const
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
void swap(_nonpod_inarray<T>& other)
|
||||
{
|
||||
std::swap(_array, other._array);
|
||||
}
|
||||
size_type max_size() const { return -1; }
|
||||
|
||||
Eina_Inarray* native_handle()
|
||||
{
|
||||
return this->_array;
|
||||
}
|
||||
Eina_Inarray const* native_handle() const
|
||||
{
|
||||
return this->_array;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class inarray : public eina::if_<eina::is_pod<T>, _pod_inarray<T>
|
||||
, _nonpod_inarray<T> >::type
|
||||
{
|
||||
typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T>
|
||||
, _nonpod_inarray<T> >::type _base_type;
|
||||
public:
|
||||
inarray() : _base_type() {}
|
||||
inarray(typename _base_type::size_type n, typename _base_type::value_type const& t)
|
||||
: _base_type(n, t) {}
|
||||
template <typename InputIterator>
|
||||
inarray(InputIterator i, InputIterator const& j
|
||||
, typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
|
||||
: _base_type(i, j)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool operator==(inarray<T> const& lhs, inarray<T> const& rhs)
|
||||
{
|
||||
return lhs.size() == rhs.size() &&
|
||||
std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator!=(inarray<T> const& lhs, inarray<T> const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void swap(inarray<T>& lhs, inarray<T>& rhs)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue