summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--configure.ac18
-rw-r--r--m4/ax_cxx_compile_stdcxx_11.m4133
-rw-r--r--pc/.gitignore1
-rw-r--r--pc/eina-cxx.pc.in12
-rw-r--r--src/Makefile.am3
-rw-r--r--src/Makefile_Eina_Cxx.am61
-rw-r--r--src/examples/eina_cxx/Makefile.am45
-rw-r--r--src/examples/eina_cxx/eina_cxx_list_01.cc55
-rw-r--r--src/examples/eina_cxx/eina_cxx_thread_01.cc32
-rw-r--r--src/lib/eina_cxx/Eina.hh44
-rw-r--r--src/lib/eina_cxx/eina_accessor.hh214
-rw-r--r--src/lib/eina_cxx/eina_clone_allocators.hh69
-rw-r--r--src/lib/eina_cxx/eina_error.hh105
-rw-r--r--src/lib/eina_cxx/eina_inarray.hh544
-rw-r--r--src/lib/eina_cxx/eina_inlist.hh464
-rw-r--r--src/lib/eina_cxx/eina_iterator.hh101
-rw-r--r--src/lib/eina_cxx/eina_lists_auxiliary.hh28
-rw-r--r--src/lib/eina_cxx/eina_ptrarray.hh486
-rw-r--r--src/lib/eina_cxx/eina_ptrlist.hh495
-rw-r--r--src/lib/eina_cxx/eina_ref.hh26
-rw-r--r--src/lib/eina_cxx/eina_stringshare.hh205
-rw-r--r--src/lib/eina_cxx/eina_thread.hh356
-rw-r--r--src/lib/eina_cxx/eina_type_traits.hh51
-rw-r--r--src/lib/eina_cxx/eina_value.hh371
-rw-r--r--src/tests/eina_cxx/eina_cxx_suite.cc125
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_accessor.cc102
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_eina_value.cc191
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_error.cc72
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_inarray.cc388
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_inlist.cc212
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_iterator.cc34
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_ptrarray.cc180
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_ptrlist.cc212
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_stringshare.cc32
-rw-r--r--src/tests/eina_cxx/eina_cxx_test_thread.cc127
36 files changed, 5595 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index f4b62572a6..db28c44ec2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,6 +119,7 @@ endif
119 119
120pkgconfig_DATA += \ 120pkgconfig_DATA += \
121pc/eina.pc \ 121pc/eina.pc \
122pc/eina-cxx.pc \
122pc/eo.pc \ 123pc/eo.pc \
123pc/eet.pc \ 124pc/eet.pc \
124pc/evas.pc \ 125pc/evas.pc \
diff --git a/configure.ac b/configure.ac
index 8f4023e2de..6f95066c93 100644
--- a/configure.ac
+++ b/configure.ac
@@ -890,6 +890,21 @@ EFL_LIB_END([Eina])
890#### End of Eina 890#### End of Eina
891 891
892 892
893#### Eina CXX
894EFL_LIB_START([Eina_Cxx])
895
896AX_CXX_COMPILE_STDCXX_11([ext])
897if test "x${HAVE_CXX11}" -a "x1"; then
898 have_cxx11="yes"
899else
900 have_cxx11="no"
901fi
902
903AM_CONDITIONAL([HAVE_CXX11], [test "x${have_cxx11}" -a "xyes"])
904
905EFL_LIB_END([Eina_Cxx])
906#### End of Eina CXX
907
893#### Eet 908#### Eet
894 909
895EFL_LIB_START([Eet]) 910EFL_LIB_START([Eet])
@@ -3927,6 +3942,7 @@ src/Makefile
3927src/benchmarks/eina/Makefile 3942src/benchmarks/eina/Makefile
3928src/benchmarks/eo/Makefile 3943src/benchmarks/eo/Makefile
3929src/examples/eina/Makefile 3944src/examples/eina/Makefile
3945src/examples/eina_cxx/Makefile
3930src/examples/eet/Makefile 3946src/examples/eet/Makefile
3931src/examples/eo/Makefile 3947src/examples/eo/Makefile
3932src/examples/evas/Makefile 3948src/examples/evas/Makefile
@@ -3945,6 +3961,7 @@ spec/efl.spec
3945pc/evil.pc 3961pc/evil.pc
3946pc/escape.pc 3962pc/escape.pc
3947pc/eina.pc 3963pc/eina.pc
3964pc/eina-cxx.pc
3948pc/eet.pc 3965pc/eet.pc
3949pc/eo.pc 3966pc/eo.pc
3950pc/evas-fb.pc 3967pc/evas-fb.pc
@@ -4075,6 +4092,7 @@ echo " Threads.......: ${efl_have_threads} (${features_thread})"
4075echo " Cryptography..: ${build_crypto}" 4092echo " Cryptography..: ${build_crypto}"
4076echo " X11...........: ${with_x11}" 4093echo " X11...........: ${with_x11}"
4077echo " OpenGL........: ${with_opengl}" 4094echo " OpenGL........: ${with_opengl}"
4095echo " C++11.........: ${have_cxx11}"
4078echo "Evas............: yes (${features_evas})" 4096echo "Evas............: yes (${features_evas})"
4079echo " Engines.......: ${features_evas_engine}" 4097echo " Engines.......: ${features_evas_engine}"
4080echo " Image Loaders.: ${features_evas_loader}" 4098echo " Image Loaders.: ${features_evas_loader}"
diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4
new file mode 100644
index 0000000000..af37acdb5c
--- /dev/null
+++ b/m4/ax_cxx_compile_stdcxx_11.m4
@@ -0,0 +1,133 @@
1# ============================================================================
2# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
3# ============================================================================
4#
5# SYNOPSIS
6#
7# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
8#
9# DESCRIPTION
10#
11# Check for baseline language coverage in the compiler for the C++11
12# standard; if necessary, add switches to CXXFLAGS to enable support.
13#
14# The first argument, if specified, indicates whether you insist on an
15# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
16# -std=c++11). If neither is specified, you get whatever works, with
17# preference for an extended mode.
18#
19# The second argument, if specified 'mandatory' or if left unspecified,
20# indicates that baseline C++11 support is required and that the macro
21# should error out if no mode with that support is found. If specified
22# 'optional', then configuration proceeds regardless, after defining
23# HAVE_CXX11 if and only if a supporting mode is found.
24#
25# LICENSE
26#
27# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
28# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
29# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
30#
31# Copying and distribution of this file, with or without modification, are
32# permitted in any medium without royalty provided the copyright notice
33# and this notice are preserved. This file is offered as-is, without any
34# warranty.
35
36#serial 3
37
38m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
39 template <typename T>
40 struct check
41 {
42 static_assert(sizeof(int) <= sizeof(T), "not big enough");
43 };
44
45 typedef check<check<bool>> right_angle_brackets;
46
47 int a;
48 decltype(a) b;
49
50 typedef check<int> check_type;
51 check_type c;
52 check_type&& cr = static_cast<check_type&&>(c);
53
54 auto d = a;
55])
56
57AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
58 m4_if([$1], [], [],
59 [$1], [ext], [],
60 [$1], [noext], [],
61 [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
62 m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
63 [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
64 [$2], [optional], [ax_cxx_compile_cxx11_required=false],
65 [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
66 AC_LANG_PUSH([C++])dnl
67 ac_success=no
68 AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
69 ax_cv_cxx_compile_cxx11,
70 [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
71 [ax_cv_cxx_compile_cxx11=yes],
72 [ax_cv_cxx_compile_cxx11=no])])
73 if test x$ax_cv_cxx_compile_cxx11 = xyes; then
74 ac_success=yes
75 fi
76
77 m4_if([$1], [noext], [], [dnl
78 if test x$ac_success = xno; then
79 for switch in -std=gnu++11 -std=gnu++0x; do
80 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
81 AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
82 $cachevar,
83 [ac_save_CXXFLAGS="$CXXFLAGS"
84 CXXFLAGS="$CXXFLAGS $switch"
85 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
86 [eval $cachevar=yes],
87 [eval $cachevar=no])
88 CXXFLAGS="$ac_save_CXXFLAGS"])
89 if eval test x\$$cachevar = xyes; then
90 CXXFLAGS="$CXXFLAGS $switch"
91 ac_success=yes
92 break
93 fi
94 done
95 fi])
96
97 m4_if([$1], [ext], [], [dnl
98 if test x$ac_success = xno; then
99 for switch in -std=c++11 -std=c++0x; do
100 cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
101 AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
102 $cachevar,
103 [ac_save_CXXFLAGS="$CXXFLAGS"
104 CXXFLAGS="$CXXFLAGS $switch"
105 AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
106 [eval $cachevar=yes],
107 [eval $cachevar=no])
108 CXXFLAGS="$ac_save_CXXFLAGS"])
109 if eval test x\$$cachevar = xyes; then
110 CXXFLAGS="$CXXFLAGS $switch"
111 ac_success=yes
112 break
113 fi
114 done
115 fi])
116 AC_LANG_POP([C++])
117 if test x$ax_cxx_compile_cxx11_required = xtrue; then
118 if test x$ac_success = xno; then
119 AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
120 fi
121 else
122 if test x$ac_success = xno; then
123 HAVE_CXX11=0
124 AC_MSG_NOTICE([No compiler with C++11 support was found])
125 else
126 HAVE_CXX11=1
127 AC_DEFINE(HAVE_CXX11,1,
128 [define if the compiler supports basic C++11 syntax])
129 fi
130
131 AC_SUBST(HAVE_CXX11)
132 fi
133])
diff --git a/pc/.gitignore b/pc/.gitignore
index b6178fb51b..1daef65f9c 100644
--- a/pc/.gitignore
+++ b/pc/.gitignore
@@ -24,6 +24,7 @@
24/efreet-trash.pc 24/efreet-trash.pc
25/efreet.pc 25/efreet.pc
26/eina.pc 26/eina.pc
27/eina-cxx.pc
27/eio.pc 28/eio.pc
28/eldbus.pc 29/eldbus.pc
29/embryo.pc 30/embryo.pc
diff --git a/pc/eina-cxx.pc.in b/pc/eina-cxx.pc.in
new file mode 100644
index 0000000000..c6571fa4ae
--- /dev/null
+++ b/pc/eina-cxx.pc.in
@@ -0,0 +1,12 @@
1prefix=@prefix@
2exec_prefix=@exec_prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: Eina C++
7Description: A C++ binding for the Eina library
8Requires.private: @requirements_pc_eina@
9Version: @VERSION@
10Libs: -L${libdir} -leina @requirements_public_libs_eina@
11Libs.private: @requirements_libs_eina@
12Cflags: -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
diff --git a/src/Makefile.am b/src/Makefile.am
index e797d57820..9abc8a919d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,8 @@ include Makefile_Emotion.am
56include Makefile_Ethumb.am 56include Makefile_Ethumb.am
57include Makefile_Ethumb_Client.am 57include Makefile_Ethumb_Client.am
58 58
59include Makefile_Eina_Cxx.am
60
59.PHONY: benchmark examples 61.PHONY: benchmark examples
60 62
61BENCHMARK_SUBDIRS = \ 63BENCHMARK_SUBDIRS = \
@@ -71,6 +73,7 @@ benchmark: all-am
71 73
72EXAMPLES_SUBDIRS = \ 74EXAMPLES_SUBDIRS = \
73examples/eina \ 75examples/eina \
76examples/eina_cxx \
74examples/eo \ 77examples/eo \
75examples/eet \ 78examples/eet \
76examples/evas \ 79examples/evas \
diff --git a/src/Makefile_Eina_Cxx.am b/src/Makefile_Eina_Cxx.am
new file mode 100644
index 0000000000..fa4888da41
--- /dev/null
+++ b/src/Makefile_Eina_Cxx.am
@@ -0,0 +1,61 @@
1
2### Library
3
4#lib_LTLIBRARIES += lib/eina/libeina.la
5
6installed_einacxxmainheadersdir = $(includedir)/eina_cxx-@VMAJ@
7dist_installed_einacxxmainheaders_DATA = \
8lib/eina_cxx/Eina.hh
9
10installed_einacxxheadersdir = $(includedir)/eina_cxx-@VMAJ@/eina_cxx
11dist_installed_einacxxheaders_DATA = \
12lib/eina_cxx/eina_accessor.hh \
13lib/eina_cxx/eina_clone_allocators.hh \
14lib/eina_cxx/eina_error.hh \
15lib/eina_cxx/eina_inarray.hh \
16lib/eina_cxx/eina_inlist.hh \
17lib/eina_cxx/eina_iterator.hh \
18lib/eina_cxx/eina_lists_auxiliary.hh \
19lib/eina_cxx/eina_ptrarray.hh \
20lib/eina_cxx/eina_ptrlist.hh \
21lib/eina_cxx/eina_ref.hh \
22lib/eina_cxx/eina_stringshare.hh \
23lib/eina_cxx/eina_thread.hh \
24lib/eina_cxx/eina_type_traits.hh \
25lib/eina_cxx/eina_value.hh
26
27### Unit tests
28
29if EFL_ENABLE_TESTS
30if HAVE_CXX11
31
32check_PROGRAMS += tests/eina_cxx/eina_cxx_suite
33TESTS += tests/eina_cxx/eina_cxx_suite
34
35tests_eina_cxx_eina_cxx_suite_SOURCES = \
36tests/eina_cxx/eina_cxx_suite.cc \
37tests/eina_cxx/eina_cxx_test_inlist.cc \
38tests/eina_cxx/eina_cxx_test_inarray.cc \
39tests/eina_cxx/eina_cxx_test_iterator.cc \
40tests/eina_cxx/eina_cxx_test_ptrarray.cc \
41tests/eina_cxx/eina_cxx_test_ptrlist.cc \
42tests/eina_cxx/eina_cxx_test_stringshare.cc \
43tests/eina_cxx/eina_cxx_test_error.cc \
44tests/eina_cxx/eina_cxx_test_accessor.cc \
45tests/eina_cxx/eina_cxx_test_thread.cc \
46tests/eina_cxx/eina_cxx_test_eina_value.cc
47
48tests_eina_cxx_eina_cxx_suite_CXXFLAGS = -I$(top_builddir)/src/lib/efl \
49-I$(top_builddir)/src/lib/eina_cxx \
50-DTESTS_WD=\"`pwd`\" \
51-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eina_cxx\" \
52-DPACKAGE_BUILD_DIR=\"`pwd`/$(top_builddir)/src/tests/eina_cxx\" \
53-DTESTS_BUILD_DIR=PACKAGE_BUILD_DIR \
54@CHECK_CFLAGS@ \
55@EINA_CFLAGS@
56tests_eina_cxx_eina_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EINA_LIBS@
57tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@
58
59endif
60endif
61
diff --git a/src/examples/eina_cxx/Makefile.am b/src/examples/eina_cxx/Makefile.am
new file mode 100644
index 0000000000..6f784b08a1
--- /dev/null
+++ b/src/examples/eina_cxx/Makefile.am
@@ -0,0 +1,45 @@
1MAINTAINERCLEANFILES = Makefile.in
2
3AM_CPPFLAGS = \
4-I$(top_builddir)/src/lib/efl \
5-I. \
6-I$(top_srcdir)/src/lib/eina \
7-I$(top_builddir)/src/lib/eina \
8-I$(top_srcdir)/src/lib/eina_cxx \
9-I$(top_builddir)/src/lib/eina_cxx
10
11LDADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LDFLAGS@ @USE_BOOST_SYSTEM_LIBS@ @USE_BOOST_SYSTEM_LDFLAGS@
12AM_CXXFLAGS = @USE_BOOST_CPPFLAGS@
13
14SRCS = \
15eina_cxx_list_01.cc
16
17EXTRA_PROGRAMS = \
18eina_cxx_list_01 \
19eina_cxx_thread_01
20
21eina_cxx_list_01_SOURCES = \
22eina_cxx_list_01.cc
23
24eina_cxx_thread_01_SOURCES = \
25eina_cxx_thread_01.cc
26
27EXTRA_DIST = $(DATA_FILES)
28
29examples: $(EXTRA_PROGRAMS)
30
31clean-local:
32 rm -f $(EXTRA_PROGRAMS)
33
34install-examples:
35 mkdir -p $(datadir)/eina/examples
36 $(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eina/examples
37
38uninstall-local:
39 for f in $(SRCS) $(DATA_FILES); do \
40 rm -f $(datadir)/eina/examples/$$f ; \
41 done
42
43if ALWAYS_BUILD_EXAMPLES
44noinst_PROGRAMS = $(EXTRA_PROGRAMS)
45endif
diff --git a/src/examples/eina_cxx/eina_cxx_list_01.cc b/src/examples/eina_cxx/eina_cxx_list_01.cc
new file mode 100644
index 0000000000..b451ef1553
--- /dev/null
+++ b/src/examples/eina_cxx/eina_cxx_list_01.cc
@@ -0,0 +1,55 @@
1//Compile with:
2//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
3
4#include <stdio.h>
5#include <Eina.hh>
6
7#include <iterator>
8#include <algorithm>
9
10#include <iostream>
11
12template <typename I>
13I next(I i, std::size_t n = 1u)
14{
15 for(;n;--n)
16 ++i;
17}
18
19int main(int argc, char **argv)
20{
21 efl::eina::eina_init eina_init;
22
23 efl::eina::ptr_list<std::string, efl::eina::heap_copy_allocator> list;
24
25 list.push_back("tigh");
26 list.push_back("adar");
27 list.push_back("baltar");
28 list.push_back("roslin");
29
30 for(efl::eina::ptr_list<std::string>::const_iterator
31 first = list.begin(), last = list.end()
32 ;first != last; ++first)
33 std::cout << *first << std::endl;
34
35 efl::eina::ptr_list<std::string>::iterator
36 iterator = ::next(list.begin(), 2u);
37 list.insert(iterator, "cain");
38
39 iterator = std::find(list.begin(), list.end(), "cain");
40 assert(iterator != list.end() && ::next(iterator) != list.end());
41 list.insert(::next(iterator), "zarek");
42
43 list.insert(list.begin(), "adama");
44
45 iterator = std::find(list.begin(), list.end(), "cain");
46 assert(iterator != list.end());
47 list.insert(iterator, "gaeta");
48
49 list.insert(::next(list.begin()), "lampkin");
50
51 for(efl::eina::ptr_list<std::string>::const_iterator
52 first = list.begin(), last = list.end()
53 ;first != last; ++first)
54 std::cout << *first << std::endl;
55}
diff --git a/src/examples/eina_cxx/eina_cxx_thread_01.cc b/src/examples/eina_cxx/eina_cxx_thread_01.cc
new file mode 100644
index 0000000000..6ce329f3e5
--- /dev/null
+++ b/src/examples/eina_cxx/eina_cxx_thread_01.cc
@@ -0,0 +1,32 @@
1//Compile with:
2//gcc -g eina_list_01.c -o eina_list_01 `pkg-config --cflags --libs eina`
3
4#include <stdio.h>
5#include <Eina.hh>
6
7#include <iterator>
8#include <algorithm>
9
10#include <iostream>
11
12namespace eina = efl::eina;
13
14void thread1(eina::mutex& m)
15{
16
17}
18
19int main(int argc, char **argv)
20{
21 eina::eina_init eina_init;
22 eina::eina_threads_init threads_init;
23
24 eina::mutex m;
25 eina::condition_variable c;
26
27 eina::unique_lock<eina::mutex> l(m);
28
29 eina::thread thread1(&::thread1, eina::ref(m));
30
31 thread1.join();
32}
diff --git a/src/lib/eina_cxx/Eina.hh b/src/lib/eina_cxx/Eina.hh
new file mode 100644
index 0000000000..7e7e985c16
--- /dev/null
+++ b/src/lib/eina_cxx/Eina.hh
@@ -0,0 +1,44 @@
1#ifndef EINA_HH_
2#define EINA_HH_
3
4#include <eina_iterator.hh>
5#include <eina_ptrarray.hh>
6#include <eina_ptrlist.hh>
7#include <eina_inarray.hh>
8#include <eina_inlist.hh>
9#include <eina_stringshare.hh>
10#include <eina_error.hh>
11#include <eina_accessor.hh>
12#include <eina_thread.hh>
13#include <eina_value.hh>
14#include <eina_ref.hh>
15
16namespace efl { namespace eina {
17
18struct eina_init
19{
20 eina_init()
21 {
22 ::eina_init();
23 }
24 ~eina_init()
25 {
26 ::eina_shutdown();
27 }
28};
29
30struct eina_threads_init
31{
32 eina_threads_init()
33 {
34 ::eina_threads_init();
35 }
36 ~eina_threads_init()
37 {
38 ::eina_threads_shutdown();
39 }
40};
41
42} }
43
44#endif
diff --git a/src/lib/eina_cxx/eina_accessor.hh b/src/lib/eina_cxx/eina_accessor.hh
new file mode 100644
index 0000000000..b389b31bf7
--- /dev/null
+++ b/src/lib/eina_cxx/eina_accessor.hh
@@ -0,0 +1,214 @@
1#ifndef EINA_ACCESSOR_HH_
2#define EINA_ACCESSOR_HH_
3
4#include <Eina.h>
5#include <eina_error.hh>
6
7#include <memory>
8#include <iterator>
9#include <cstdlib>
10#include <cassert>
11
12namespace efl { namespace eina {
13
14template <typename T>
15struct accessor
16{
17 typedef unsigned int key_type;
18 typedef T mapped_type;
19 typedef T value_type;
20 typedef std::size_t size_type;
21
22 accessor() : _impl(0) {}
23 explicit accessor(Eina_Accessor* impl)
24 : _impl(impl)
25 {
26 assert(_impl != 0);
27 }
28 accessor(accessor<T> const& other)
29 : _impl(eina_accessor_clone(other._impl))
30 {}
31 accessor<T>& operator=(accessor<T> const& other)
32 {
33 eina_accessor_free(_impl);
34 _impl = eina_accessor_clone(other._impl);
35 if(!_impl)
36 throw eina::system_error(efl::eina::get_error_code(), "Error cloning accessor");
37 return *this;
38 }
39 ~accessor()
40 {
41 eina_accessor_free(_impl);
42 }
43
44 mapped_type& operator[](size_type i) const
45 {
46 assert(_impl != 0);
47 void* p;
48 if(!eina_accessor_data_get(_impl, i, &p))
49 {
50 eina::error_code ec = efl::eina::get_error_code();
51 throw eina::system_error(ec, "EFL Eina Error");
52 }
53 return *static_cast<mapped_type*>(p);
54 }
55
56 Eina_Accessor* native_handle() const;
57
58 void swap(accessor<T>& other)
59 {
60 std::swap(_impl, other._impl);
61 }
62private:
63 typedef Eina_Accessor*(accessor<T>::*unspecified_bool_type)() const;
64public:
65 operator unspecified_bool_type() const
66 {
67 return native_handle() ? &accessor<T>::native_handle : 0 ;
68 }
69private:
70 Eina_Accessor* _impl;
71};
72
73template <typename U>
74void swap(accessor<U>& lhs, accessor<U>& rhs)
75{
76 lhs.swap(rhs);
77}
78
79template <typename T>
80struct accessor_iterator
81{
82 typedef T value_type;
83 typedef value_type* pointer;
84 typedef value_type& reference;
85 typedef std::ptrdiff_t difference_type;
86 typedef std::random_access_iterator_tag iterator_category;
87
88 accessor_iterator(accessor<T> const& a, unsigned int pos = 0u)
89 : _accessor(a), _index(pos)
90 {}
91
92 accessor_iterator<T>& operator+=(difference_type i)
93 {
94 _index += i;
95 return *this;
96 }
97 accessor_iterator<T>& operator-=(difference_type i)
98 {
99 _index -= i;
100 return *this;
101 }
102 value_type& operator[](difference_type i)
103 {
104 return _accessor[_index + i];
105 }
106 accessor_iterator<T>& operator++()
107 {
108 ++_index;
109 return *this;
110 }
111 accessor_iterator<T>& operator--()
112 {
113 --_index;
114 return *this;
115 }
116 accessor_iterator<T>& operator++(int)
117 {
118 accessor_iterator<T> tmp(*this);
119 ++*this;
120 return tmp;
121 }
122 accessor_iterator<T>& operator--(int)
123 {
124 accessor_iterator<T> tmp(*this);
125 --*this;
126 return tmp;
127 }
128 value_type& operator*() const
129 {
130 return _accessor[_index];
131 }
132 pointer operator->() const
133 {
134 return &**this;
135 }
136 void swap(accessor_iterator<T>& other)
137 {
138 std::swap(_index, other._index);
139 std::swap(_accessor, other._accessor);
140 }
141private:
142 accessor<T> _accessor;
143 unsigned int _index;
144
145 template <typename U>
146 friend bool operator==(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
147 {
148 return lhs._index == rhs._index;
149 }
150
151 template <typename U>
152 friend typename accessor_iterator<U>::difference_type
153 operator-(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
154 {
155 return lhs._index - rhs._index;
156 }
157
158 template <typename U>
159 friend
160 accessor_iterator<U> operator+(accessor_iterator<U> lhs
161 , typename accessor_iterator<U>::difference_type rhs)
162 {
163 lhs._index += rhs;
164 return lhs;
165 }
166
167 template <typename U>
168 friend
169 accessor_iterator<U> operator+(typename accessor_iterator<U>::difference_type lhs
170 , accessor_iterator<U> rhs)
171 {
172 return rhs + lhs;
173 }
174
175 template <typename U>
176 friend bool operator<(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
177 {
178 return lhs._index < rhs._index;
179 }
180
181 template <typename U>
182 friend bool operator<=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
183 {
184 return lhs._index <= rhs._index;
185 }
186};
187
188template <typename U>
189bool operator>=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
190{
191 return !(lhs < rhs);
192}
193
194template <typename U>
195bool operator>(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
196{
197 return !(lhs <= rhs);
198}
199
200template <typename U>
201bool operator!=(accessor_iterator<U> const& lhs, accessor_iterator<U> const& rhs)
202{
203 return !(lhs == rhs);
204}
205
206template <typename U>
207void swap(accessor_iterator<U>& lhs, accessor_iterator<U>& rhs)
208{
209 lhs.swap(rhs);
210}
211
212} }
213
214#endif
diff --git a/src/lib/eina_cxx/eina_clone_allocators.hh b/src/lib/eina_cxx/eina_clone_allocators.hh
new file mode 100644
index 0000000000..6f7aba49eb
--- /dev/null
+++ b/src/lib/eina_cxx/eina_clone_allocators.hh
@@ -0,0 +1,69 @@
1#ifndef EINA_CLONE_ALLOCATORS_HH_
2#define EINA_CLONE_ALLOCATORS_HH_
3
4#include <memory>
5
6namespace efl { namespace eina {
7
8struct heap_copy_allocator
9{
10 template <typename T>
11 static T* allocate_clone(T const& v)
12 {
13 return new T(v);
14 }
15
16 template <typename T>
17 static void deallocate_clone(T* p)
18 {
19#ifdef EFL_EINA_CXX11
20 std::default_delete<T>()(p);
21#else
22 delete p;
23#endif
24 }
25};
26
27struct heap_clone_allocator
28{
29 template <typename T>
30 static T* allocate_clone(T const& v)
31 {
32 return new_clone(v);
33 }
34 template <typename T>
35 static void deallocate_clone(T* p)
36 {
37 delete_clone(p);
38 }
39};
40
41struct view_clone_allocator
42{
43 template <typename T>
44 static T* allocate_clone(T const& v)
45 {
46 return const_cast<T*>(&v);
47 }
48 template <typename T>
49 static void deallocate_clone(T* p)
50 {
51 }
52};
53
54struct heap_no_copy_allocator
55{
56 template <typename T>
57 static void deallocate_clone(T* p)
58 {
59#ifdef EFL_EINA_CXX11
60 std::default_delete<T>()(p);
61#else
62 delete p;
63#endif
64 }
65};
66
67} }
68
69#endif
diff --git a/src/lib/eina_cxx/eina_error.hh b/src/lib/eina_cxx/eina_error.hh
new file mode 100644
index 0000000000..1199e694b9
--- /dev/null
+++ b/src/lib/eina_cxx/eina_error.hh
@@ -0,0 +1,105 @@
1#ifndef _EINA_ERROR_HH
2#define _EINA_ERROR_HH
3
4#include <Eina.h>
5
6#include <system_error>
7
8namespace efl { namespace eina {
9
10using std::errc;
11using std::system_error;
12using std::error_code;
13using std::error_condition;
14typedef std::error_category system_error_category;
15
16inline system_error_category const& get_generic_category()
17{
18 return ::std::generic_category();
19}
20inline system_error_category const& get_system_category()
21{
22 return ::std::system_category();
23}
24
25enum error_type {};
26
27struct error_category : system_error_category
28{
29 const char* name() const throw()
30 {
31 return "eina";
32 }
33
34 bool equivalent(int code, eina::error_condition const& condition) const throw()
35 {
36 return code == condition.value();
37 }
38
39 bool equivalent(eina::error_code const& code, int condition) const throw()
40 {
41 return code.value() == condition;
42 }
43
44 std::string message(int condition) const
45 {
46 const char* e = ::eina_error_msg_get(condition);
47 return e? e : "::eina_error_msg_get returned NULL. No error message available";
48 }
49};
50
51inline eina::system_error_category& eina_error_category()
52{
53 static error_category _error_category;
54 return _error_category;
55}
56
57inline eina::error_code get_error_code()
58{
59 Eina_Error error = eina_error_get();
60 if(error)
61 {
62 eina_error_set(0);
63 return eina::error_code(error, eina_error_category());
64 }
65 else
66 return eina::error_code();
67}
68
69inline eina::error_condition get_error_condition()
70{
71 Eina_Error error = eina_error_get();
72 if(error)
73 {
74 eina_error_set(0);
75 return eina::error_condition(error, eina_error_category());
76 }
77 else
78 return eina::error_condition();
79}
80
81inline error_type get_error_code_enum()
82{
83 return static_cast<error_type>( ::eina_error_get() );
84}
85
86
87inline void throw_on_error()
88{
89 eina::error_code ec = get_error_code();
90 if(ec)
91 {
92 throw eina::system_error(ec, "EFL Eina Error");
93 }
94}
95
96} }
97
98namespace std {
99
100template <> struct is_error_condition_enum< ::efl::eina::error_type> : true_type {};
101template <> struct is_error_code_enum< ::efl::eina::error_type> : true_type {};
102
103}
104
105#endif
diff --git a/src/lib/eina_cxx/eina_inarray.hh b/src/lib/eina_cxx/eina_inarray.hh
new file mode 100644
index 0000000000..3619358bad
--- /dev/null
+++ b/src/lib/eina_cxx/eina_inarray.hh
@@ -0,0 +1,544 @@
1#ifndef EINA_INARRAY_HH_
2#define EINA_INARRAY_HH_
3
4#include <Eina.h>
5#include <eina_type_traits.hh>
6
7#include <iterator>
8#include <cstring>
9#include <cassert>
10
11namespace efl { namespace eina {
12
13struct _inarray_common_base
14{
15 typedef std::size_t size_type;
16
17 explicit _inarray_common_base(size_type member_size)
18 : _array( ::eina_inarray_new(member_size, 0) )
19 {
20 }
21 ~_inarray_common_base()
22 {
23 ::eina_inarray_free(_array);
24 }
25
26 size_type size() const
27 {
28 return ::eina_inarray_count(_array);
29 }
30 bool empty() const
31 {
32 return size() == 0u;
33 }
34
35 Eina_Inarray* _array;
36private:
37 _inarray_common_base(_inarray_common_base const& other);
38 _inarray_common_base& operator=(_inarray_common_base const& other);
39};
40
41template <typename T>
42class _pod_inarray : _inarray_common_base
43{
44 typedef _inarray_common_base _base_type;
45public:
46 typedef T value_type;
47 typedef T& reference;
48 typedef T const& const_reference;
49 typedef T* pointer;
50 typedef T const* const_pointer;
51 typedef pointer iterator;
52 typedef const_pointer const_iterator;
53 typedef std::size_t size_type;
54 typedef std::ptrdiff_t difference_type;
55
56 typedef std::reverse_iterator<iterator> reverse_iterator;
57 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
58
59 using _base_type::size;
60 using _base_type::empty;
61
62 _pod_inarray() : _base_type(sizeof(T))
63 {
64 }
65 _pod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
66 {
67 while(n--)
68 push_back(t);
69 }
70 template <typename InputIterator>
71 _pod_inarray(InputIterator i, InputIterator const& j
72 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
73 : _base_type(sizeof(T))
74 {
75 while(i != j)
76 {
77 push_back(*i);
78 ++i;
79 }
80 }
81 _pod_inarray(_pod_inarray<T>const& other)
82 : _base_type(sizeof(T))
83 {
84 insert(end(), other.begin(), other.end());
85 }
86 ~_pod_inarray()
87 {
88 }
89 _pod_inarray<T>& operator=(_pod_inarray<T>const& other)
90 {
91 clear();
92 insert(end(), other.begin(), other.end());
93 return *this;
94 }
95 void clear()
96 {
97 ::eina_inarray_flush(_array);
98 }
99 void push_back(T const& value)
100 {
101 eina_inarray_push(_array, &value);
102 }
103 void pop_back()
104 {
105 eina_inarray_pop(_array);
106 }
107 iterator insert(iterator i, value_type const& t)
108 {
109 if(i != end())
110 {
111 T* q = static_cast<iterator>
112 ( ::eina_inarray_alloc_at(_array, i - begin(), 1u));
113 std::memcpy(q, &t, sizeof(t));
114 return q;
115 }
116 else
117 {
118 push_back(t);
119 return end()-1;
120 }
121 }
122 iterator insert(iterator i, size_t n, value_type const& t)
123 {
124 T* q;
125 if(i != end())
126 {
127 q = static_cast<iterator>
128 ( ::eina_inarray_alloc_at(_array, i - &_array->members, n));
129 }
130 else
131 {
132 q = eina_inarray_grow(_array, n);
133 }
134 for(T* p = q; n; --n, ++p)
135 std::memcpy(p, &t, sizeof(t));
136 return q;
137 }
138 template <typename InputIterator>
139 iterator insert(iterator p, InputIterator i, InputIterator j
140 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
141 {
142 size_type n = 0;
143 while(i != j)
144 {
145 p = insert(p, *i);
146 ++p;
147 ++i;
148 ++n;
149 }
150 return p - n;
151 }
152 iterator erase(iterator q)
153 {
154 ::eina_inarray_remove_at(_array, q - begin());
155 return q;
156 }
157 iterator erase(iterator i, iterator j)
158 {
159 while(i != j)
160 {
161 erase(--j);
162 }
163 return i;
164 }
165 template <typename InputIterator>
166 void assign(InputIterator i, InputIterator j
167 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
168 void assign(size_type n, value_type const& t);
169 value_type& back()
170 {
171 assert(!empty());
172 return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
173 }
174 value_type const& back() const
175 {
176 return const_cast<_pod_inarray<T>&>(*this).back();
177 }
178 value_type& front()
179 {
180 assert(!empty());
181 return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
182 }
183 value_type const& front() const
184 {
185 return const_cast<_pod_inarray<T>&>(*this).front();
186 }
187 iterator begin()
188 {
189 return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, 0u));
190 }
191 iterator end()
192 {
193 return !_array->members ? 0 : static_cast<iterator>(::eina_inarray_nth(_array, size()-1)) + 1;
194 }
195 const_iterator begin() const
196 {
197 return const_cast< _pod_inarray<T>&>(*this).begin();
198 }
199 const_iterator end() const
200 {
201 return const_cast< _pod_inarray<T>&>(*this).end();
202 }
203 const_reverse_iterator rbegin() const
204 {
205 return const_reverse_iterator(begin());
206 }
207 const_reverse_iterator rend() const
208 {
209 return const_reverse_iterator(end());
210 }
211 reverse_iterator rbegin()
212 {
213 return reverse_iterator(begin());
214 }
215 reverse_iterator rend()
216 {
217 return reverse_iterator(end());
218 }
219 const_iterator cbegin() const
220 {
221 return begin();
222 }
223 const_iterator cend() const
224 {
225 return end();
226 }
227 const_reverse_iterator crbegin() const
228 {
229 return rbegin();
230 }
231 const_reverse_iterator crend() const
232 {
233 return rend();
234 }
235 void swap(_pod_inarray<T>& other)
236 {
237 std::swap(_array, other._array);
238 }
239 size_type max_size() const { return -1; }
240
241 Eina_Inarray* native_handle()
242 {
243 return this->_array;
244 }
245 Eina_Inarray const* native_handle() const
246 {
247 return this->_array;
248 }
249};
250
251template <typename T>
252class _nonpod_inarray : _inarray_common_base
253{
254 typedef _inarray_common_base _base_type;
255public:
256 typedef T value_type;
257 typedef T& reference;
258 typedef T const& const_reference;
259 typedef T* pointer;
260 typedef T const* const_pointer;
261 typedef pointer iterator;
262 typedef const_pointer const_iterator;
263 typedef std::size_t size_type;
264 typedef std::ptrdiff_t difference_type;
265
266 typedef std::reverse_iterator<iterator> reverse_iterator;
267 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
268
269 using _base_type::size;
270 using _base_type::empty;
271
272 _nonpod_inarray() : _base_type(sizeof(T))
273 {
274 }
275 _nonpod_inarray(size_type n, value_type const& t) : _base_type(sizeof(T))
276 {
277 while(n--)
278 push_back(t);
279 }
280 template <typename InputIterator>
281 _nonpod_inarray(InputIterator i, InputIterator const& j
282 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
283 : _base_type(sizeof(T))
284 {
285 while(i != j)
286 {
287 push_back(*i);
288 ++i;
289 }
290 }
291 _nonpod_inarray(_nonpod_inarray<T>const& other)
292 : _base_type(sizeof(T))
293 {
294 insert(end(), other.begin(), other.end());
295 }
296 ~_nonpod_inarray()
297 {
298 for(T* first = static_cast<T*>(_array->members)
299 , *last = first + _array->len; first != last; ++first)
300 first->~T();
301 }
302 _nonpod_inarray<T>& operator=(_nonpod_inarray<T>const& other)
303 {
304 clear();
305 insert(end(), other.begin(), other.end());
306 return *this;
307 }
308 void clear()
309 {
310 for(T* first = static_cast<T*>(_array->members)
311 , *last = first + _array->len; first != last; ++first)
312 first->~T();
313 ::eina_inarray_flush(_array);
314 }
315 void push_back(T const& value)
316 {
317 insert(end(), 1u, value);
318 }
319 void pop_back()
320 {
321 T* elem = static_cast<T*>(_array->members) + _array->len - 1;
322 elem->~T();
323 eina_inarray_pop(_array);
324 }
325 iterator insert(iterator i, value_type const& t)
326 {
327 return insert(i, 1u, t);
328 }
329 iterator insert(iterator i, size_t n, value_type const& t)
330 {
331 if(_array->max - _array->len >= n)
332 {
333 iterator end = static_cast<T*>(_array->members)
334 + _array->len
335 , last = end + n;
336 _array->len += n;
337 std::reverse_iterator<iterator>
338 dest(last), src(end), src_end(i);
339 for(;src != src_end; ++src)
340 {
341 if(dest.base() <= end)
342 *dest++ = *src;
343 else
344 new (&*dest++) T(*src);
345 }
346 iterator j = i;
347 for(size_type i = 0;i != n;++i)
348 {
349 if(j < end)
350 *j = t;
351 else
352 new (&*j++) T(t);
353 }
354 }
355 else
356 {
357 size_type index = i - static_cast<iterator>(_array->members);
358
359 Eina_Inarray* old_array = eina_inarray_new(_array->member_size, 0);
360 *old_array = *_array;
361 _array->len = _array->max = 0;
362 _array->members = 0;
363 eina_inarray_resize(_array, old_array->len+n);
364 _array->len = old_array->len+n;
365
366 iterator old_first = static_cast<iterator>(old_array->members)
367 , first = begin()
368 , last = first + _array->len;
369 i = index + begin();
370
371 while(first != i)
372 {
373 new (&*first++) T(*old_first);
374 old_first++->~T();
375 }
376 for(size_type i = 0;i != n;++i)
377 new (&*first++) T(t);
378 assert(last - first == _array->len - index - n);
379 while(first != last)
380 {
381 new (&*first++) T(*old_first);
382 old_first++->~T();
383 }
384 }
385 return i;
386 }
387 template <typename InputIterator>
388 iterator insert(iterator p, InputIterator i, InputIterator j
389 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
390 {
391 size_type n = 0;
392 while(i != j)
393 {
394 p = insert(p, *i);
395 ++p;
396 ++i;
397 ++n;
398 }
399 return p - n;
400 }
401 iterator erase(iterator q)
402 {
403 return erase(q, q+1);
404 }
405 iterator erase(iterator i, iterator j)
406 {
407 iterator last = end();
408 iterator k = i, l = j;
409 while(l != last)
410 *k++ = *l++;
411 while(k != last)
412 k++->~T();
413 _array->len -= j - i;
414
415 return i;
416 }
417 template <typename InputIterator>
418 void assign(InputIterator i, InputIterator j
419 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0);
420 void assign(size_type n, value_type const& t);
421 value_type& back()
422 {
423 assert(!empty());
424 return *static_cast<value_type*>(eina_inarray_nth(_array, size()-1u));
425 }
426 value_type const& back() const
427 {
428 return const_cast<_nonpod_inarray<T>&>(*this).back();
429 }
430 value_type& front()
431 {
432 assert(!empty());
433 return *static_cast<value_type*>(eina_inarray_nth(_array, 0u));
434 }
435 value_type const& front() const
436 {
437 return const_cast<_nonpod_inarray<T>&>(*this).front();
438 }
439 iterator begin()
440 {
441 return static_cast<iterator>(_array->members);
442 }
443 iterator end()
444 {
445 return static_cast<iterator>(_array->members) + _array->len;
446 }
447 const_iterator begin() const
448 {
449 return const_cast< _nonpod_inarray<T>&>(*this).begin();
450 }
451 const_iterator end() const
452 {
453 return const_cast< _nonpod_inarray<T>&>(*this).end();
454 }
455 const_reverse_iterator rbegin() const
456 {
457 return const_reverse_iterator(begin());
458 }
459 const_reverse_iterator rend() const
460 {
461 return const_reverse_iterator(end());
462 }
463 reverse_iterator rbegin()
464 {
465 return reverse_iterator(begin());
466 }
467 reverse_iterator rend()
468 {
469 return reverse_iterator(end());
470 }
471 const_iterator cbegin() const
472 {
473 return begin();
474 }
475 const_iterator cend() const
476 {
477 return end();
478 }
479 const_reverse_iterator crbegin() const
480 {
481 return rbegin();
482 }
483 const_reverse_iterator crend() const
484 {
485 return rend();
486 }
487 void swap(_nonpod_inarray<T>& other)
488 {
489 std::swap(_array, other._array);
490 }
491 size_type max_size() const { return -1; }
492
493 Eina_Inarray* native_handle()
494 {
495 return this->_array;
496 }
497 Eina_Inarray const* native_handle() const
498 {
499 return this->_array;
500 }
501};
502
503template <typename T>
504class inarray : public eina::if_<eina::is_pod<T>, _pod_inarray<T>
505 , _nonpod_inarray<T> >::type
506{
507 typedef typename eina::if_<eina::is_pod<T>, _pod_inarray<T>
508 , _nonpod_inarray<T> >::type _base_type;
509public:
510 inarray() : _base_type() {}
511 inarray(typename _base_type::size_type n, typename _base_type::value_type const& t)
512 : _base_type(n, t) {}
513 template <typename InputIterator>
514 inarray(InputIterator i, InputIterator const& j
515 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
516 : _base_type(i, j)
517 {}
518
519};
520
521template <typename T>
522bool operator==(inarray<T> const& lhs, inarray<T> const& rhs)
523{
524 return lhs.size() == rhs.size() &&
525 std::equal(lhs.begin(), lhs.end(), rhs.begin());
526}
527
528template <typename T>
529bool operator!=(inarray<T> const& lhs, inarray<T> const& rhs)
530{
531 return !(lhs == rhs);
532}
533
534template <typename T>
535void swap(inarray<T>& lhs, inarray<T>& rhs)
536{
537 lhs.swap(rhs);
538}
539
540
541
542} }
543
544#endif
diff --git a/src/lib/eina_cxx/eina_inlist.hh b/src/lib/eina_cxx/eina_inlist.hh
new file mode 100644
index 0000000000..168b262c53
--- /dev/null
+++ b/src/lib/eina_cxx/eina_inlist.hh
@@ -0,0 +1,464 @@
1#ifndef EINA_INLIST_HH_
2#define EINA_INLIST_HH_
3
4#include <Eina.h>
5#include <eina_lists_auxiliary.hh>
6#include <eina_type_traits.hh>
7#include <eina_accessor.hh>
8
9#include <iterator>
10
11namespace efl { namespace eina {
12
13template <typename T>
14struct _inlist_node
15{
16 EINA_INLIST;
17 T object;
18};
19
20template <typename T>
21_inlist_node<T>* _get_node(Eina_Inlist* l)
22{
23 return static_cast<_inlist_node<T>*>(static_cast<void*>(l));
24}
25
26template <typename T>
27_inlist_node<T> const* _get_node(Eina_Inlist const* l)
28{
29 return const_cast<Eina_Inlist*>(l);
30}
31
32template <typename T>
33Eina_Inlist* _get_list(_inlist_node<T>* n)
34{
35 if(n)
36 return EINA_INLIST_GET(n);
37 else
38 return 0;
39}
40
41template <typename T>
42Eina_Inlist const* _get_list(_inlist_node<T> const* n)
43{
44 return _get_list(const_cast<_inlist_node<T>*>(n));
45}
46
47template <typename T>
48struct _inlist_iterator
49{
50 typedef T value_type;
51 typedef T* pointer;
52 typedef T& reference;
53 typedef std::ptrdiff_t difference_type;
54 typedef std::bidirectional_iterator_tag iterator_category;
55
56 _inlist_iterator() {}
57 explicit _inlist_iterator(_inlist_node<T>* list, _inlist_node<T>* node)
58 : _list(list), _node(node) {}
59
60 _inlist_iterator<T>& operator++()
61 {
62 _node = _get_node<T>(_node->__in_list.next);
63 return *this;
64 }
65 _inlist_iterator<T> operator++(int)
66 {
67 _inlist_iterator<T> tmp(*this);
68 ++*this;
69 return tmp;
70 }
71 _inlist_iterator<T>& operator--()
72 {
73 if(_node)
74 _node = _get_node<T>(_node->__in_list.prev);
75 else
76 _node = _get_node<T>(_list->__in_list.last);
77 return *this;
78 }
79 _inlist_iterator<T> operator--(int)
80 {
81 _inlist_iterator<T> tmp(*this);
82 --*this;
83 return tmp;
84 }
85 T const& operator*() const
86 {
87 return _node->object;
88 }
89 T const* operator->() const
90 {
91 return &_node->object;
92 }
93 _inlist_node<T>* native_handle()
94 {
95 return _node;
96 }
97 _inlist_node<T> const* native_handle() const
98 {
99 return _node;
100 }
101private:
102 _inlist_node<T>* _list;
103 _inlist_node<T>* _node;
104
105 friend bool operator==(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
106 {
107 return lhs._node == rhs._node;
108 }
109};
110
111template <typename T>
112bool operator!=(_inlist_iterator<T> lhs, _inlist_iterator<T> rhs)
113{
114 return !(lhs == rhs);
115}
116
117template <typename T, typename Allocator>
118struct _inlist_common_base
119{
120 typedef typename Allocator::template rebind<_inlist_node<T> >::other node_allocator_type;
121 typedef Allocator allocator_type;
122 typedef _inlist_node<T> node_type;
123
124 _inlist_common_base(Allocator allocator)
125 : _impl(allocator) {}
126 _inlist_common_base()
127 {}
128 ~_inlist_common_base()
129 {
130 clear();
131 }
132
133 void clear()
134 {
135 Eina_Inlist* p = _impl._list;
136 Eina_Inlist* q;
137 while(p)
138 {
139 q = p->next;
140
141 _inlist_node<T>* node = _get_node<T>(p);
142 node->~_inlist_node<T>();
143 get_node_allocator().deallocate(node, 1);
144
145 p = q;
146 }
147 _impl._list = 0;
148 }
149 node_allocator_type& get_node_allocator()
150 {
151 return _impl;
152 }
153
154 // For EBO
155 struct _inlist_impl : node_allocator_type
156 {
157 _inlist_impl(Allocator allocator)
158 : node_allocator_type(allocator), _list(0)
159 {}
160 _inlist_impl() : _list(0) {}
161
162 Eina_Inlist* _list;
163 };
164
165 _inlist_impl _impl;
166private:
167 _inlist_common_base(_inlist_common_base const& other);
168 _inlist_common_base& operator=(_inlist_common_base const& other);
169};
170
171template <typename T, typename Allocator = std::allocator<T> >
172class inlist : protected _inlist_common_base<T, Allocator>
173{
174 typedef _inlist_common_base<T, Allocator> _base_type;
175 typedef typename _base_type::node_type _node_type;
176public:
177 typedef typename _base_type::allocator_type allocator_type;
178 typedef typename allocator_type::value_type value_type;
179 typedef typename allocator_type::reference reference;
180 typedef typename allocator_type::const_reference const_reference;
181 typedef _inlist_iterator<T const> const_iterator;
182 typedef _inlist_iterator<T> iterator;
183 typedef typename allocator_type::pointer pointer;
184 typedef typename allocator_type::const_pointer const_pointer;
185 typedef std::size_t size_type;
186 typedef std::ptrdiff_t difference_type;
187
188 typedef std::reverse_iterator<iterator> reverse_iterator;
189 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
190
191 using _base_type::clear;
192
193 inlist() {}
194 inlist(size_type n, value_type const& t)
195 {
196 while(n--)
197 push_back(t);
198 }
199 template <typename InputIterator>
200 inlist(InputIterator i, InputIterator const& j
201 , allocator_type const& alloc = allocator_type()
202 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
203 : _base_type(alloc)
204 {
205 while(i != j)
206 {
207 push_back(*i);
208 ++i;
209 }
210 }
211 inlist(inlist<T, Allocator>const& other)
212 : _base_type()
213 {
214 insert(end(), other.begin(), other.end());
215 }
216 inlist<T, Allocator>& operator=(inlist<T, Allocator>const& other)
217 {
218 clear();
219 insert(end(), other.begin(), other.end());
220 return *this;
221 }
222 size_type size() const
223 {
224 return ::eina_inlist_count(this->_impl._list);
225 }
226 bool empty() const
227 {
228 return this->_impl._list == 0;
229 }
230 allocator_type get_allocator() const
231 {
232 return allocator_type(this->get_node_allocator());
233 }
234 void push_back(T const& value)
235 {
236 _node_type* node ( this->get_node_allocator().allocate(1) );
237 try
238 {
239 new (&node->object) T(value);
240 // eina_inlist_append can't fail
241 this->_impl._list = eina_inlist_append(this->_impl._list, _get_list(node));
242 }
243 catch(...)
244 {
245 this->get_node_allocator().deallocate(node, 1);
246 throw;
247 }
248 }
249 void push_front(T const& value)
250 {
251 _node_type* node ( this->get_node_allocator().allocate(1) );
252 try
253 {
254 new (&node->object) T(value);
255 // eina_inlist_prepend can't fail
256 this->_impl._list = eina_inlist_prepend(this->_impl._list, _get_list(node));
257 }
258 catch(...)
259 {
260 this->get_node_allocator().deallocate(node, 1);
261 throw;
262 }
263 }
264 void pop_back()
265 {
266 this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list->last);
267 }
268 void pop_front()
269 {
270 this->_impl._list = eina_inlist_remove(this->_impl._list, this->_impl._list);
271 }
272 iterator insert(iterator i, value_type const& t)
273 {
274 _node_type* node ( this->get_node_allocator().allocate(1) );
275 try
276 {
277 new (&node->object) T(t);
278 // eina_inlist_prepend_relative can't fail
279 this->_impl._list = _eina_inlist_prepend_relative
280 (this->_impl._list, _get_list(node)
281 , _get_list(i.native_handle()));
282 return iterator(_get_node<T>(this->_impl._list), node);
283 }
284 catch(...)
285 {
286 this->get_node_allocator().deallocate(node, 1);
287 throw;
288 }
289 }
290 iterator insert(iterator i, size_t n, value_type const& t)
291 {
292 iterator r = i;
293 if(n--)
294 r = insert(i, t);
295 while(n--)
296 insert(i, t);
297 return r;
298 }
299
300 template <typename InputIterator>
301 iterator insert(iterator p, InputIterator i, InputIterator j
302 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
303 {
304 iterator r = p;
305 if(i != j)
306 {
307 value_type v = *i;
308 r = insert(p, v);
309 ++i;
310 }
311 while(i != j)
312 {
313 insert(p, *i);
314 ++i;
315 }
316 return r;
317 }
318
319 iterator erase(iterator q)
320 {
321 if(q.native_handle())
322 {
323 iterator r(_get_node<T>(this->_impl._list), _get_node<T>(_get_list(q.native_handle())->next));
324 this->_impl._list = eina_inlist_remove(this->_impl._list, _get_list(q.native_handle()));
325 return r;
326 }
327 else
328 return q;
329 }
330
331 iterator erase(iterator i, iterator j)
332 {
333 while(i != j)
334 i = erase(i);
335 if(j.native_handle())
336 return j;
337 else
338 return end();
339 }
340
341 template <typename InputIterator>
342 void assign(InputIterator i, InputIterator j
343 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
344 {
345 clear();
346 insert(end(), i, j);
347 }
348
349 void assign(size_type n, value_type const& t)
350 {
351 clear();
352 insert(end(), n, t);
353 }
354
355 value_type& back()
356 {
357 return _get_node<T>(this->_impl._list->last)->object;
358 }
359 value_type const& back() const
360 {
361 return const_cast<inlist<T, Allocator>&>(*this).back();
362 }
363 value_type& front()
364 {
365 return _get_node<T>(this->_impl._list)->object;
366 }
367 value_type const& front() const
368 {
369 return const_cast<inlist<T, Allocator>&>(*this).front();
370 }
371 const_iterator begin() const
372 {
373 return const_iterator(_get_node<T const>(this->_impl._list), _get_node<T const>(this->_impl._list));
374 }
375 const_iterator end() const
376 {
377 return const_iterator(_get_node<T const>(this->_impl._list), 0);
378 }
379 iterator begin()
380 {
381 return iterator(_get_node<T>(this->_impl._list), _get_node<T>(this->_impl._list));
382 }
383 iterator end()
384 {
385 return iterator(_get_node<T>(this->_impl._list), 0);
386 }
387 const_reverse_iterator rbegin() const
388 {
389 return const_reverse_iterator(begin());
390 }
391 const_reverse_iterator rend() const
392 {
393 return const_reverse_iterator(end());
394 }
395 reverse_iterator rbegin()
396 {
397 return reverse_iterator(begin());
398 }
399 reverse_iterator rend()
400 {
401 return reverse_iterator(end());
402 }
403 const_iterator cbegin() const
404 {
405 return begin();
406 }
407 const_iterator cend() const
408 {
409 return end();
410 }
411 const_reverse_iterator crbegin() const
412 {
413 return rbegin();
414 }
415 const_reverse_iterator crend() const
416 {
417 return rend();
418 }
419 void swap(inlist<T, Allocator>& other)
420 {
421 std::swap(this->_impl._list, other._impl._list);
422 }
423 size_type max_size() const { return -1; }
424
425 Eina_Inlist* native_handle()
426 {
427 return this->_impl._list;
428 }
429 Eina_Inlist const* native_handle() const
430 {
431 return this->_impl._list;
432 }
433 eina::accessor<T const> accessor() const
434 {
435 return eina::accessor<T const>(eina_inlist_accessor_new(this->_impl._list));
436 }
437 eina::accessor<T> accessor()
438 {
439 return eina::accessor<T>(eina_inlist_accessor_new(this->_impl._list));
440 }
441};
442
443template <typename T, typename Allocator1, typename Allocator2>
444bool operator==(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
445{
446 return lhs.size() == rhs.size() &&
447 std::equal(lhs.begin(), lhs.end(), rhs.begin());
448}
449
450template <typename T, typename Allocator1, typename Allocator2>
451bool operator!=(inlist<T, Allocator1> const& lhs, inlist<T, Allocator2> const& rhs)
452{
453 return !(lhs == rhs);
454}
455
456template <typename T, typename Allocator>
457void swap(inlist<T, Allocator>& lhs, inlist<T, Allocator>& rhs)
458{
459 lhs.swap(rhs);
460}
461
462} }
463
464#endif
diff --git a/src/lib/eina_cxx/eina_iterator.hh b/src/lib/eina_cxx/eina_iterator.hh
new file mode 100644
index 0000000000..d10401c0c0
--- /dev/null
+++ b/src/lib/eina_cxx/eina_iterator.hh
@@ -0,0 +1,101 @@
1#ifndef EINA_ITERATOR_HH_
2#define EINA_ITERATOR_HH_
3
4#include <Eina.h>
5
6#include <cstdlib>
7#include <iterator>
8
9namespace efl { namespace eina {
10
11template <typename T>
12struct _common_iterator_base
13{
14private:
15 typedef _common_iterator_base<T> self_type;
16public:
17 typedef T const value_type;
18 typedef value_type* pointer;
19 typedef value_type& reference;
20 typedef std::ptrdiff_t difference_type;
21 typedef std::input_iterator_tag iterator_category;
22
23 _common_iterator_base() {}
24 explicit _common_iterator_base(Eina_Iterator* iterator)
25 : _iterator(iterator) {}
26 ~_common_iterator_base()
27 {
28 if(_iterator)
29 eina_iterator_free(_iterator);
30 }
31 _common_iterator_base(self_type const& other)
32 : _iterator(other._iterator)
33 {
34 other._iterator = 0;
35 }
36 _common_iterator_base& operator=(self_type const& other)
37 {
38 _iterator = other._iterator;
39 other._iterator = 0;
40 return *this;
41 }
42
43protected:
44 mutable Eina_Iterator* _iterator;
45
46 friend inline bool operator==(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
47 {
48 return lhs._iterator == rhs._iterator;
49 }
50 friend inline bool operator!=(_common_iterator_base<T> const& lhs, _common_iterator_base<T> const& rhs)
51 {
52 return !(lhs == rhs);
53 }
54};
55
56template <typename T>
57struct iterator : _common_iterator_base<T const>
58{
59private:
60 typedef _common_iterator_base<T const> base_type;
61 typename base_type::pointer _value;
62 typedef iterator<T> self_type;
63public:
64 typedef typename base_type::value_type value_type;
65 typedef typename base_type::pointer pointer;
66 typedef typename base_type::reference reference;
67 typedef typename base_type::difference_type difference_type;
68 typedef typename base_type::iterator_category iterator_category;
69
70 explicit iterator(Eina_Iterator* iterator = 0)
71 : base_type(iterator)
72 {
73 if(this->_iterator)
74 ++*this;
75 }
76 self_type& operator++()
77 {
78 void* data;
79 Eina_Bool r = ::eina_iterator_next(this->_iterator, &data);
80 if(!r)
81 this->_iterator = 0;
82 _value = static_cast<pointer>(data);
83 return *this;
84 }
85 self_type& operator++(int)
86 {
87 return ++**this;
88 }
89 value_type& operator*() const
90 {
91 return *_value;
92 }
93 pointer operator->() const
94 {
95 return _value;
96 }
97};
98
99} }
100
101#endif
diff --git a/src/lib/eina_cxx/eina_lists_auxiliary.hh b/src/lib/eina_cxx/eina_lists_auxiliary.hh
new file mode 100644
index 0000000000..ebcbfd6016
--- /dev/null
+++ b/src/lib/eina_cxx/eina_lists_auxiliary.hh
@@ -0,0 +1,28 @@
1#ifndef _EINA_LISTS_AUXILIARY_HH
2#define _EINA_LISTS_AUXILIARY_HH
3
4#include <Eina.h>
5
6namespace efl { namespace eina {
7
8inline Eina_List* _eina_list_prepend_relative_list(Eina_List* list, const void* data, Eina_List* relative) EINA_ARG_NONNULL(2)
9{
10 if(relative)
11 return ::eina_list_prepend_relative_list(list, data, relative);
12 else
13 return ::eina_list_append(list, data);
14}
15
16inline Eina_Inlist *_eina_inlist_prepend_relative(Eina_Inlist *in_list,
17 Eina_Inlist *in_item,
18 Eina_Inlist *in_relative) EINA_ARG_NONNULL(2)
19{
20 if(in_relative)
21 return ::eina_inlist_prepend_relative(in_list, in_item, in_relative);
22 else
23 return ::eina_inlist_append(in_list, in_item);
24}
25
26} }
27
28#endif
diff --git a/src/lib/eina_cxx/eina_ptrarray.hh b/src/lib/eina_cxx/eina_ptrarray.hh
new file mode 100644
index 0000000000..7b0e88b6ed
--- /dev/null
+++ b/src/lib/eina_cxx/eina_ptrarray.hh
@@ -0,0 +1,486 @@
1#ifndef EINA_PTRARRAY_HH_
2#define EINA_PTRARRAY_HH_
3
4#include <Eina.h>
5#include <eina_clone_allocators.hh>
6#include <eina_lists_auxiliary.hh>
7#include <eina_type_traits.hh>
8
9#include <memory>
10#include <iterator>
11#include <cstdlib>
12#include <cassert>
13
14namespace efl { namespace eina {
15
16struct _ptr_array_iterator_base
17{
18 _ptr_array_iterator_base() : _ptr(0) {}
19 _ptr_array_iterator_base(void** ptr)
20 : _ptr(ptr)
21 {}
22
23 void** _ptr;
24};
25
26template <typename T>
27struct _ptr_array_iterator : protected _ptr_array_iterator_base
28{
29 typedef T value_type;
30 typedef value_type* pointer;
31 typedef value_type& reference;
32 typedef std::ptrdiff_t difference_type;
33 typedef std::bidirectional_iterator_tag iterator_category;
34
35 _ptr_array_iterator() {}
36 explicit _ptr_array_iterator(void** ptr)
37 : _ptr_array_iterator_base(ptr)
38
39 {
40 }
41 _ptr_array_iterator(_ptr_array_iterator<typename remove_cv<value_type>::type> const& other)
42 : _ptr_array_iterator_base(static_cast<_ptr_array_iterator_base const&>(other))
43 {
44 }
45
46 _ptr_array_iterator<T>& operator++()
47 {
48 ++_ptr;
49 return *this;
50 }
51 _ptr_array_iterator<T> operator++(int)
52 {
53 _ptr_array_iterator<T> tmp(*this);
54 ++*this;
55 return tmp;
56 }
57 _ptr_array_iterator<T>& operator--()
58 {
59 --_ptr;
60 return *this;
61 }
62 _ptr_array_iterator<T> operator--(int)
63 {
64 _ptr_array_iterator<T> tmp(*this);
65 --*this;
66 return tmp;
67 }
68 reference operator*() const
69 {
70 return *static_cast<pointer>(*_ptr);
71 }
72 pointer operator->() const
73 {
74 return &**this;
75 }
76 void** native_handle() const
77 {
78 return _ptr;
79 }
80 friend inline bool operator==(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs)
81 {
82 return lhs._ptr == rhs._ptr;
83 }
84 friend inline bool operator!=(_ptr_array_iterator<T> lhs, _ptr_array_iterator<T> rhs)
85 {
86 return !(lhs == rhs);
87 }
88 friend inline _ptr_array_iterator<T> operator+(_ptr_array_iterator<T> lhs
89 , difference_type size)
90 {
91 lhs._ptr += size;
92 return lhs;
93 }
94 friend inline _ptr_array_iterator<T> operator-(_ptr_array_iterator<T> lhs
95 , difference_type size)
96 {
97 lhs._ptr -= size;
98 return lhs;
99 }
100 friend inline difference_type operator-(_ptr_array_iterator<T> lhs
101 , _ptr_array_iterator<T> rhs)
102 {
103 return lhs._ptr - rhs._ptr;
104 }
105};
106
107template <typename T, typename CloneAllocator>
108struct _ptr_array_common_base
109{
110 typedef CloneAllocator clone_allocator_type;
111
112 _ptr_array_common_base(CloneAllocator clone_allocator)
113 : _impl(clone_allocator)
114 {}
115 _ptr_array_common_base(Eina_Array* _array)
116 : _impl(_array)
117 {}
118 _ptr_array_common_base() {}
119
120 CloneAllocator& _get_clone_allocator()
121 {
122 return _impl;
123 }
124 CloneAllocator const& _get_clone_allocator() const
125 {
126 return _impl;
127 }
128 void _delete_clone(T const* p)
129 {
130 _get_clone_allocator().deallocate_clone(p);
131 }
132 T* _new_clone(T const& a)
133 {
134 return _get_clone_allocator().allocate_clone(a);
135 }
136
137 struct _ptr_array_impl : CloneAllocator
138 {
139 _ptr_array_impl() : _array( ::eina_array_new(32u) ) {}
140 _ptr_array_impl(CloneAllocator allocator)
141 : clone_allocator_type(allocator), _array( ::eina_array_new(32u)) {}
142
143 Eina_Array* _array;
144 };
145
146 _ptr_array_impl _impl;
147
148private:
149 _ptr_array_common_base(_ptr_array_common_base const& other);
150 _ptr_array_common_base& operator=(_ptr_array_common_base const& other);
151};
152
153template <typename T, typename CloneAllocator = heap_no_copy_allocator>
154class ptr_array : protected _ptr_array_common_base<T, CloneAllocator>
155{
156 typedef _ptr_array_common_base<T, CloneAllocator> _base_type;
157public:
158 typedef T value_type;
159 typedef T& reference;
160 typedef T const& const_reference;
161 typedef _ptr_array_iterator<T const> const_iterator;
162 typedef _ptr_array_iterator<T> iterator;
163 typedef T* pointer;
164 typedef T const* const_pointer;
165 typedef std::size_t size_type;
166 typedef std::ptrdiff_t difference_type;
167 typedef CloneAllocator clone_allocator_type;
168
169 typedef std::reverse_iterator<iterator> reverse_iterator;
170 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
171
172 ptr_array() {}
173 ptr_array(size_type n, const_reference t)
174 {
175 while(n--)
176 push_back(t);
177 }
178 template <typename InputIterator>
179 ptr_array(InputIterator i, InputIterator const& j
180 , clone_allocator_type const& alloc = clone_allocator_type()
181 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
182 : _base_type(alloc)
183 {
184 while(i != j)
185 {
186 push_back(*i);
187 ++i;
188 }
189 }
190 ptr_array(ptr_array<T, CloneAllocator> const& other)
191 : _base_type()
192 {
193 insert(end(), other.begin(), other.end());
194 }
195 template <typename CloneAllocator1>
196 ptr_array(ptr_array<T, CloneAllocator1>const& other)
197 : _base_type()
198 {
199 insert(end(), other.begin(), other.end());
200 }
201 ~ptr_array()
202 {
203 clear();
204 }
205 ptr_array<T, CloneAllocator>& operator=(ptr_array<T, CloneAllocator>const& other)
206 {
207 clear();
208 insert(end(), other.begin(), other.end());
209 return *this;
210 }
211
212 void clear()
213 {
214 for(iterator first = begin(), last = end(); first != last; ++first)
215 this->_delete_clone(&*first);
216 eina_array_flush(this->_impl._array);
217 }
218 std::size_t size() const
219 {
220 return eina_array_count(this->_impl._array);
221 }
222 bool empty() const
223 {
224 return size() == 0u;
225 }
226 clone_allocator_type get_clone_allocator() const
227 {
228 return clone_allocator_type(this->_get_clone_allocator());
229 }
230 void push_back(const_reference a)
231 {
232 push_back(this->_new_clone(a));
233 }
234 void push_back(pointer p)
235 {
236 std::auto_ptr<value_type> p1(p);
237 push_back(p1);
238 }
239 void push_back(std::auto_ptr<T>& p)
240 {
241 if(eina_array_push(this->_impl._array, p.get()))
242 p.release();
243 else
244 throw std::bad_alloc();
245 }
246 void pop_back()
247 {
248 eina_array_pop(this->_impl._array);
249 }
250 iterator insert(iterator i, value_type const& t)
251 {
252 return insert(i, this->_new_clone(t));
253 }
254 iterator insert(iterator i, pointer pv)
255 {
256 std::auto_ptr<value_type> p(pv);
257 return insert(i, p);
258 }
259 iterator insert(iterator i, std::auto_ptr<value_type>& p)
260 {
261 std::size_t j
262 = i.native_handle() - this->_impl._array->data
263 , size = this->size();
264 if(eina_array_push(this->_impl._array, p.get()))
265 {
266 if(size - j)
267 {
268 memmove(
269 this->_impl._array->data + j + 1
270 , this->_impl._array->data + j
271 , (size - j)*sizeof(void*));
272 // PRE: Q:[j, size) = [j+1, size+1)
273 pointer* data = static_cast<pointer*>
274 (static_cast<void*>(this->_impl._array->data));
275 data[j] = p.get();
276 }
277 p.release();
278 return iterator(this->_impl._array->data + j);
279 }
280 else
281 throw std::bad_alloc();
282 }
283 iterator insert(iterator i, size_t n, value_type const& t)
284 {
285 iterator r = i;
286 if(n--)
287 r = insert(i, t);
288 while(n--)
289 insert(i, t);
290 return r;
291 }
292 iterator insert(iterator i, size_t n, pointer p)
293 {
294 iterator r = i;
295 if(n--)
296 r = insert(i, p);
297 while(n--)
298 insert(i, this->_new_clone(p));
299 return r;
300 }
301 template <typename InputIterator>
302 iterator insert(iterator p, InputIterator i, InputIterator j
303 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
304 {
305 size_type index = p.native_handle() - this->_impl._array->data;
306 while(i != j)
307 {
308 p = insert(p, this->_new_clone(*i));
309 ++p;
310 ++i;
311 }
312 return iterator(this->_impl._array->data + index);
313 }
314 iterator erase(iterator q)
315 {
316 size_type size = this->size()
317 , i = q.native_handle() - this->_impl._array->data;
318 memmove(q.native_handle()
319 , q.native_handle() + 1
320 , (size - i - 1)*sizeof(void*));
321 eina_array_pop(this->_impl._array);
322 return q;
323 }
324 iterator erase(iterator i, iterator j)
325 {
326 size_type size = this->size()
327 , distance = std::distance(i, j);
328 memmove(i.native_handle()
329 , j.native_handle()
330 , (size - distance)*sizeof(void*));
331 while(distance--)
332 eina_array_pop(this->_impl._array);
333 return i;
334 }
335 template <typename InputIterator>
336 void assign(InputIterator i, InputIterator j
337 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
338 {
339 clear();
340 insert(end(), i, j);
341 }
342 void assign(size_type n, value_type const& t)
343 {
344 clear();
345 insert(end(), n, t);
346 }
347
348 value_type& back()
349 {
350 return *static_cast<pointer>(this->_impl._array->data[size()-1]);
351 }
352 value_type const& back() const
353 {
354 return const_cast<ptr_array<T, CloneAllocator>&>(*this).back();
355 }
356 value_type& front()
357 {
358 return *static_cast<pointer>(this->_impl._array->data[0]);
359 }
360 value_type const& front() const
361 {
362 return const_cast<ptr_array<T, CloneAllocator>&>(*this).front();
363 }
364
365 const_reference operator[](size_type index) const
366 {
367 pointer data = static_cast<pointer>
368 (this->_impl._array->data[index]);
369 return *data;
370 }
371 reference operator[](size_type index)
372 {
373 return const_cast<reference>
374 (const_cast<ptr_array<T, CloneAllocator>const&>(*this)[index]);
375 }
376
377 const_iterator begin() const
378 {
379 return const_iterator(this->_impl._array->data);
380 }
381 const_iterator end() const
382 {
383 return const_iterator(this->_impl._array->data + size());
384 }
385 iterator begin()
386 {
387 return iterator(this->_impl._array->data);
388 }
389 iterator end()
390 {
391 return iterator(this->_impl._array->data + size());
392 }
393 const_reverse_iterator rbegin() const
394 {
395 return const_reverse_iterator(begin());
396 }
397 const_reverse_iterator rend() const
398 {
399 return const_reverse_iterator(end());
400 }
401 reverse_iterator rbegin()
402 {
403 return reverse_iterator(begin());
404 }
405 reverse_iterator rend()
406 {
407 return reverse_iterator(end());
408 }
409 const_iterator cbegin() const
410 {
411 return begin();
412 }
413 const_iterator cend() const
414 {
415 return end();
416 }
417 const_reverse_iterator crbegin() const
418 {
419 return rbegin();
420 }
421 const_reverse_iterator crend() const
422 {
423 return rend();
424 }
425 eina::iterator<T> ibegin()
426 {
427 return eina::iterator<T>( ::eina_array_iterator_new(this->_impl._array) );
428 }
429 eina::iterator<T> iend()
430 {
431 return eina::iterator<T>();
432 }
433 eina::iterator<T const> ibegin() const
434 {
435 return eina::iterator<T const>( ::eina_array_iterator_new(this->_impl._array) );
436 }
437 eina::iterator<T const> iend() const
438 {
439 return eina::iterator<T const>();
440 }
441 eina::iterator<T const> cibegin() const
442 {
443 return ibegin();
444 }
445 eina::iterator<T const> ciend() const
446 {
447 return iend();
448 }
449 void swap(ptr_array<T, CloneAllocator>& other)
450 {
451 std::swap(this->_impl._array, other._impl._array);
452 }
453 size_type max_size() const { return -1; }
454
455 Eina_Array* native_handle()
456 {
457 return this->_impl._array;
458 }
459 Eina_Array const* native_handle() const
460 {
461 return this->_impl._array;
462 }
463};
464
465template <typename T, typename CloneAllocator1, typename CloneAllocator2>
466bool operator==(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
467{
468 return lhs.size() == rhs.size()
469 && std::equal(lhs.begin(), lhs.end(), rhs.begin());
470}
471
472template <typename T, typename CloneAllocator1, typename CloneAllocator2>
473bool operator!=(ptr_array<T, CloneAllocator1> const& lhs, ptr_array<T, CloneAllocator2> const& rhs)
474{
475 return !(lhs == rhs);
476}
477
478template <typename T, typename CloneAllocator>
479void swap(ptr_array<T, CloneAllocator>& lhs, ptr_array<T, CloneAllocator>& rhs)
480{
481 lhs.swap(rhs);
482}
483
484} }
485
486#endif
diff --git a/src/lib/eina_cxx/eina_ptrlist.hh b/src/lib/eina_cxx/eina_ptrlist.hh
new file mode 100644
index 0000000000..b9132872b7
--- /dev/null
+++ b/src/lib/eina_cxx/eina_ptrlist.hh
@@ -0,0 +1,495 @@
1#ifndef EINA_LIST_HH_
2#define EINA_LIST_HH_
3
4#include <Eina.h>
5#include <eina_clone_allocators.hh>
6#include <eina_lists_auxiliary.hh>
7#include <eina_type_traits.hh>
8#include <eina_accessor.hh>
9
10#include <memory>
11#include <iterator>
12
13namespace efl { namespace eina {
14
15struct _ptr_list_iterator_base
16{
17 typedef std::ptrdiff_t difference_type;
18 typedef std::bidirectional_iterator_tag iterator_category;
19
20 _ptr_list_iterator_base() : _list(0) {}
21 _ptr_list_iterator_base(Eina_List* list, Eina_List* node)
22 : _list(list), _node(node)
23 {}
24
25protected:
26 Eina_List *_list, *_node;
27};
28
29template <typename T>
30struct _ptr_list_iterator : _ptr_list_iterator_base
31{
32 typedef T value_type;
33 typedef value_type* pointer;
34 typedef value_type& reference;
35
36 _ptr_list_iterator() {}
37 explicit _ptr_list_iterator(Eina_List* list, Eina_List* node)
38 : _ptr_list_iterator_base(list, node)
39 {
40 }
41 _ptr_list_iterator(_ptr_list_iterator<typename remove_cv<value_type>::type> const& other)
42 : _ptr_list_iterator_base(static_cast<_ptr_list_iterator_base const&>(other))
43 {
44 }
45
46 _ptr_list_iterator<T>& operator++()
47 {
48 _node = eina_list_next(_node);
49 return *this;
50 }
51 _ptr_list_iterator<T> operator++(int)
52 {
53 _ptr_list_iterator<T> tmp(*this);
54 ++*this;
55 return tmp;
56 }
57 _ptr_list_iterator<T>& operator--()
58 {
59 if(_node)
60 _node = eina_list_prev(_node);
61 else
62 _node = eina_list_last(_list);
63 return *this;
64 }
65 _ptr_list_iterator<T> operator--(int)
66 {
67 _ptr_list_iterator<T> tmp(*this);
68 --*this;
69 return tmp;
70 }
71 reference operator*() const
72 {
73 void* data = eina_list_data_get(_node);
74 return *static_cast<pointer>(data);
75 }
76 pointer operator->() const
77 {
78 return &**this;
79 }
80 Eina_List* native_handle()
81 {
82 return _node;
83 }
84 Eina_List const* native_handle() const
85 {
86 return _node;
87 }
88 friend inline bool operator==(_ptr_list_iterator<T> lhs, _ptr_list_iterator<T> rhs)
89 {
90 return lhs._node == rhs._node;
91 }
92 friend inline bool operator!=(_ptr_list_iterator<T> lhs, _ptr_list_iterator<T> rhs)
93 {
94 return !(lhs == rhs);
95 }
96};
97
98template <typename T, typename CloneAllocator>
99struct _ptr_list_common_base
100{
101 typedef CloneAllocator clone_allocator_type;
102
103 _ptr_list_common_base(CloneAllocator clone_allocator)
104 : _impl(clone_allocator)
105 {}
106 _ptr_list_common_base(Eina_List* _list)
107 : _impl(_list)
108 {}
109 _ptr_list_common_base() {}
110
111 CloneAllocator& _get_clone_allocator()
112 {
113 return _impl;
114 }
115 CloneAllocator const& _get_clone_allocator() const
116 {
117 return _impl;
118 }
119 void _delete_clone(T const* p)
120 {
121 _get_clone_allocator().deallocate_clone(p);
122 }
123 T* _new_clone(T const& a)
124 {
125 return _get_clone_allocator().allocate_clone(a);
126 }
127
128 struct _ptr_list_impl : CloneAllocator
129 {
130 _ptr_list_impl() : _list(0) {}
131 _ptr_list_impl(CloneAllocator allocator)
132 : clone_allocator_type(allocator), _list(0) {}
133
134 Eina_List* _list;
135 };
136
137 _ptr_list_impl _impl;
138
139private:
140 _ptr_list_common_base(_ptr_list_common_base const& other);
141 _ptr_list_common_base& operator=(_ptr_list_common_base const& other);
142};
143
144template <typename T, typename CloneAllocator = heap_no_copy_allocator>
145class ptr_list : protected _ptr_list_common_base<T, CloneAllocator>
146{
147 typedef _ptr_list_common_base<T, CloneAllocator> _base_type;
148public:
149 typedef T value_type;
150 typedef T& reference;
151 typedef T const& const_reference;
152 typedef _ptr_list_iterator<T const> const_iterator;
153 typedef _ptr_list_iterator<T> iterator;
154 typedef T* pointer;
155 typedef T const* const_pointer;
156 typedef std::size_t size_type;
157 typedef std::ptrdiff_t difference_type;
158 typedef CloneAllocator clone_allocator_type;
159
160 typedef std::reverse_iterator<iterator> reverse_iterator;
161 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
162
163 ptr_list() {}
164 ptr_list(size_type n, const_reference t)
165 {
166 while(n--)
167 push_back(t);
168 }
169 template <typename InputIterator>
170 ptr_list(InputIterator i, InputIterator const& j
171 , clone_allocator_type const& alloc = clone_allocator_type()
172 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
173 : _base_type(alloc)
174 {
175 while(i != j)
176 {
177 push_back(*i);
178 ++i;
179 }
180 }
181 ptr_list(ptr_list<T, CloneAllocator> const& other)
182 : _base_type()
183 {
184 insert(end(), other.begin(), other.end());
185 }
186 template <typename CloneAllocator1>
187 ptr_list(ptr_list<T, CloneAllocator1>const& other)
188 : _base_type()
189 {
190 insert(end(), other.begin(), other.end());
191 }
192 ~ptr_list()
193 {
194 clear();
195 }
196 ptr_list<T, CloneAllocator>& operator=(ptr_list<T, CloneAllocator>const& other)
197 {
198 clear();
199 insert(end(), other.begin(), other.end());
200 return *this;
201 }
202
203 void clear()
204 {
205 for(iterator first = begin(), last = end(); first != last; ++first)
206 this->_delete_clone(&*first);
207 eina_list_free(this->_impl._list);
208 this->_impl._list = 0;
209 }
210 std::size_t size() const
211 {
212 return eina_list_count(this->_impl._list);
213 }
214 bool empty() const
215 {
216 return size() == 0u;
217 }
218 clone_allocator_type get_clone_allocator() const
219 {
220 return clone_allocator_type(this->_get_clone_allocator());
221 }
222 void push_back(const_reference a)
223 {
224 push_back(this->_new_clone(a));
225 }
226 void push_back(pointer p)
227 {
228 std::auto_ptr<value_type> p1(p);
229 push_back(p1);
230 }
231 void push_back(std::auto_ptr<T>& p)
232 {
233 Eina_List* new_list = eina_list_append(this->_impl._list, p.get());
234 if(new_list)
235 {
236 this->_impl._list = new_list;
237 p.release();
238 }
239 else
240 throw std::bad_alloc();
241 }
242 void push_front(const_reference a)
243 {
244 push_front(this->new_clone(a));
245 }
246 void push_front(pointer p)
247 {
248 std::auto_ptr<value_type> p1(p);
249 push_front(p1);
250 }
251 void push_front(std::auto_ptr<T>& p)
252 {
253 Eina_List* new_list = eina_list_prepend(this->_impl._list, p.get());
254 if(new_list)
255 {
256 this->_impl._list = new_list;
257 p.release();
258 }
259 else
260 throw std::bad_alloc();
261 }
262 void pop_back()
263 {
264 this->_impl._list = eina_list_remove_list(this->_impl._list, eina_list_last(this->_impl._list));
265 }
266 void pop_front()
267 {
268 this->_impl._list = eina_list_remove_list(this->_impl._list, this->_impl._list);
269 }
270 iterator insert(iterator i, value_type const& t)
271 {
272 return insert(i, this->_new_clone(t));
273 }
274 iterator insert(iterator i, pointer pv)
275 {
276 std::auto_ptr<value_type> p(pv);
277 return insert(i, p);
278 }
279 iterator insert(iterator i, std::auto_ptr<value_type>& p)
280 {
281 this->_impl._list = _eina_list_prepend_relative_list
282 (this->_impl._list, p.get(), i.native_handle());
283 if(this->_impl._list)
284 p.release();
285 else
286 throw std::bad_alloc();
287 return iterator(this->_impl._list
288 , i.native_handle()
289 ? ::eina_list_prev(i.native_handle())
290 : ::eina_list_last(this->_impl._list)
291 );
292 }
293 iterator insert(iterator i, size_t n, value_type const& t)
294 {
295 iterator r = i;
296 if(n--)
297 r = insert(i, t);
298 while(n--)
299 insert(i, t);
300 return r;
301 }
302 iterator insert(iterator i, size_t n, pointer p)
303 {
304 iterator r = i;
305 if(n--)
306 r = insert(i, p);
307 while(n--)
308 insert(i, this->_new_clone(p));
309 return r;
310 }
311 template <typename InputIterator>
312 iterator insert(iterator p, InputIterator i, InputIterator j
313 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
314 {
315 iterator r = p;
316 if(i != j)
317 {
318 r = insert(p, *i);
319 ++i;
320 }
321 while(i != j)
322 {
323 insert(p, this->_new_clone(*i));
324 ++i;
325 }
326 return r;
327 }
328 iterator erase(iterator q)
329 {
330 if(q.native_handle())
331 {
332 iterator r(this->_impl._list, eina_list_next(q.native_handle()));
333 this->_impl._list = eina_list_remove_list(this->_impl._list, q.native_handle());
334 return r;
335 }
336 else
337 return q;
338 }
339 iterator erase(iterator i, iterator j)
340 {
341 while(i != j)
342 i = erase(i);
343 if(j.native_handle())
344 return j;
345 else
346 return end();
347 }
348 template <typename InputIterator>
349 void assign(InputIterator i, InputIterator j
350 , typename eina::enable_if<!eina::is_integral<InputIterator>::value>::type* = 0)
351 {
352 clear();
353 insert(end(), i, j);
354 }
355 void assign(size_type n, value_type const& t)
356 {
357 clear();
358 insert(end(), n, t);
359 }
360
361 value_type& back()
362 {
363 return *static_cast<pointer>(eina_list_data_get(eina_list_last(this->_impl._list)));
364 }
365 value_type const& back() const
366 {
367 return const_cast<ptr_list<T, CloneAllocator>&>(*this).back();
368 }
369 value_type& front()
370 {
371 return *static_cast<pointer>(eina_list_data_get(this->_impl._list));
372 }
373 value_type const& front() const
374 {
375 return const_cast<ptr_list<T, CloneAllocator>&>(*this).front();
376 }
377
378 const_iterator begin() const
379 {
380 return const_iterator(this->_impl._list, this->_impl._list);
381 }
382 const_iterator end() const
383 {
384 return const_iterator(this->_impl._list, 0);
385 }
386 iterator begin()
387 {
388 return iterator(this->_impl._list, this->_impl._list);
389 }
390 iterator end()
391 {
392 return iterator(this->_impl._list, 0);
393 }
394 const_reverse_iterator rbegin() const
395 {
396 return const_reverse_iterator(begin());
397 }
398 const_reverse_iterator rend() const
399 {
400 return const_reverse_iterator(end());
401 }
402 reverse_iterator rbegin()
403 {
404 return reverse_iterator(begin());
405 }
406 reverse_iterator rend()
407 {
408 return reverse_iterator(end());
409 }
410 const_iterator cbegin() const
411 {
412 return begin();
413 }
414 const_iterator cend() const
415 {
416 return end();
417 }
418 const_reverse_iterator crbegin() const
419 {
420 return rbegin();
421 }
422 const_reverse_iterator crend() const
423 {
424 return rend();
425 }
426 eina::iterator<T> ibegin()
427 {
428 return eina::iterator<T>( ::eina_list_iterator_new(this->_impl._list) );
429 }
430 eina::iterator<T> iend()
431 {
432 return eina::iterator<T>();
433 }
434 eina::iterator<T const> ibegin() const
435 {
436 return eina::iterator<T const>( ::eina_list_iterator_new(this->_impl._list) );
437 }
438 eina::iterator<T const> iend() const
439 {
440 return eina::iterator<T const>();
441 }
442 eina::iterator<T const> cibegin() const
443 {
444 return ibegin();
445 }
446 eina::iterator<T const> ciend() const
447 {
448 return iend();
449 }
450 void swap(ptr_list<T, CloneAllocator>& other)
451 {
452 std::swap(this->_impl._list, other._impl._list);
453 }
454 size_type max_size() const { return -1; }
455
456 Eina_List* native_handle()
457 {
458 return this->_impl._list;
459 }
460 Eina_List const* native_handle() const
461 {
462 return this->_impl._list;
463 }
464 eina::accessor<T const> accessor() const
465 {
466 return eina::accessor<T const>(eina_list_accessor_new(this->_impl._list));
467 }
468 eina::accessor<T> accessor()
469 {
470 return eina::accessor<T>(eina_list_accessor_new(this->_impl._list));
471 }
472};
473
474template <typename T, typename CloneAllocator1, typename CloneAllocator2>
475bool operator==(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
476{
477 return lhs.size() == rhs.size()
478 && std::equal(lhs.begin(), lhs.end(), rhs.begin());
479}
480
481template <typename T, typename CloneAllocator1, typename CloneAllocator2>
482bool operator!=(ptr_list<T, CloneAllocator1> const& lhs, ptr_list<T, CloneAllocator2> const& rhs)
483{
484 return !(lhs == rhs);
485}
486
487template <typename T, typename CloneAllocator>
488void swap(ptr_list<T, CloneAllocator>& lhs, ptr_list<T, CloneAllocator>& rhs)
489{
490 lhs.swap(rhs);
491}
492
493} }
494
495#endif
diff --git a/src/lib/eina_cxx/eina_ref.hh b/src/lib/eina_cxx/eina_ref.hh
new file mode 100644
index 0000000000..887a21f769
--- /dev/null
+++ b/src/lib/eina_cxx/eina_ref.hh
@@ -0,0 +1,26 @@
1#ifndef EINA_REF_HH
2#define EINA_REF_HH
3
4#include <functional>
5
6namespace efl { namespace eina {
7
8using std::ref;
9using std::cref;
10using std::reference_wrapper;
11
12template <typename T>
13T& unref(T& t)
14{
15 return t;
16}
17
18template <typename T>
19T& unref(reference_wrapper<T> t)
20{
21 return t.get();
22}
23
24}}
25
26#endif
diff --git a/src/lib/eina_cxx/eina_stringshare.hh b/src/lib/eina_cxx/eina_stringshare.hh
new file mode 100644
index 0000000000..9638547c90
--- /dev/null
+++ b/src/lib/eina_cxx/eina_stringshare.hh
@@ -0,0 +1,205 @@
1#ifndef _EINA_STRINGSHARE_HH
2#define _EINA_STRINGSHARE_HH
3
4#include <Eina.h>
5#include <eina_type_traits.hh>
6
7#include <cstring>
8#include <stdexcept>
9
10namespace efl { namespace eina {
11
12struct steal_stringshare_ref_t {};
13steal_stringshare_ref_t const steal_stringshare_ref = {};
14
15struct stringshare
16{
17 typedef char value_type;
18 typedef value_type& reference;
19 typedef value_type const& const_reference;
20 typedef value_type* pointer;
21 typedef value_type const* const_pointer;
22 typedef const_pointer const_iterator;
23 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
24 typedef std::ptrdiff_t difference_type;
25 typedef std::size_t size_type;
26
27 stringshare()
28 : _string( ::eina_stringshare_add("") )
29 {}
30 stringshare(const char* str)
31 : _string( ::eina_stringshare_add(str) )
32 {
33 }
34 stringshare(char* str, steal_stringshare_ref_t)
35 : _string( str )
36 {
37 }
38 template <typename InputIterator>
39 stringshare(InputIterator i, InputIterator j
40 , typename eina::enable_if
41 <!eina::is_integral<InputIterator>::value
42 && !eina::is_contiguous_iterator<InputIterator>::value
43 >::type* = 0)
44 {
45 std::string tmp;
46 while(i != j)
47 {
48 tmp.push_back(*i);
49 ++i;
50 }
51 _string = ::eina_stringshare_add(tmp.c_str());
52 }
53 template <typename ContiguousMemoryIterator>
54 stringshare(ContiguousMemoryIterator i, ContiguousMemoryIterator j
55 , typename eina::enable_if
56 <eina::is_contiguous_iterator<ContiguousMemoryIterator>::value>::type* = 0)
57 : _string( ::eina_stringshare_add_length(&*i, j - i) )
58 {
59 }
60
61 ~stringshare()
62 {
63 ::eina_stringshare_del(_string);
64 }
65
66 stringshare(stringshare const& other)
67 : _string( eina_stringshare_ref(other._string) )
68 {}
69 stringshare& operator=(stringshare const& other)
70 {
71 ::eina_stringshare_refplace(&_string, other._string);
72 return *this;
73 }
74 stringshare& operator=(const char* c_string)
75 {
76 ::eina_stringshare_replace(&_string, c_string);
77 return *this;
78 }
79
80 const_iterator begin() const
81 {
82 return _string;
83 }
84 const_iterator end() const
85 {
86 return _string + size();
87 }
88
89 const_reverse_iterator rbegin() const
90 {
91 return const_reverse_iterator(begin());
92 }
93 const_reverse_iterator rend() const
94 {
95 return const_reverse_iterator(end());
96 }
97
98 const_iterator cbegin() const
99 {
100 return begin();
101 }
102 const_iterator cend() const
103 {
104 return end();
105 }
106 const_reverse_iterator crbegin() const
107 {
108 return rbegin();
109 }
110 const_reverse_iterator crend() const
111 {
112 return rend();
113 }
114
115 size_type size() const
116 {
117 return eina_stringshare_strlen(_string);
118 }
119
120 size_type length() const
121 {
122 return size();
123 }
124 size_type max_size() const
125 {
126 return -1;
127 }
128 bool empty() const
129 {
130 return _string[0] == 0;
131 }
132 const_reference operator[](size_type i) const
133 {
134 return _string[i];
135 }
136 const_reference at(size_type i) const
137 {
138 if(i < size())
139 return (*this)[i];
140 else
141 throw std::out_of_range("");
142 }
143 const_reference back() const
144 {
145 return _string[size()-1];
146 }
147 const_reference front() const
148 {
149 return _string[0];
150 }
151
152 void swap(stringshare& other)
153 {
154 std::swap(_string, other._string);
155 }
156
157 const char* c_str() const
158 {
159 return _string;
160 }
161 const char* data() const
162 {
163 return _string;
164 }
165
166private:
167 Eina_Stringshare* _string;
168};
169
170template <>
171struct is_contiguous_iterator<stringshare::const_iterator> : true_type {};
172
173inline bool operator==(stringshare const& lhs, stringshare const& rhs)
174{
175 return lhs.c_str() == rhs.c_str();
176}
177
178inline bool operator!=(stringshare const& lhs, stringshare const& rhs)
179{
180 return !(lhs == rhs);
181}
182
183inline bool operator==(stringshare const& lhs, const char* rhs)
184{
185 return lhs.c_str() == rhs || std::strcmp(lhs.c_str(), rhs) == 0;
186}
187
188inline bool operator!=(stringshare const& lhs, const char* rhs)
189{
190 return !(lhs == rhs);
191}
192
193inline bool operator==(const char* lhs, stringshare const& rhs)
194{
195 return rhs == lhs;
196}
197
198inline bool operator!=(const char* lhs, stringshare const& rhs)
199{
200 return !(lhs == rhs);
201}
202
203} }
204
205#endif
diff --git a/src/lib/eina_cxx/eina_thread.hh b/src/lib/eina_cxx/eina_thread.hh
new file mode 100644
index 0000000000..bb630a5d27
--- /dev/null
+++ b/src/lib/eina_cxx/eina_thread.hh
@@ -0,0 +1,356 @@
1#ifndef EINA_THREAD_HH_
2#define EINA_THREAD_HH_
3
4#include <Eina.h>
5#include <eina_error.hh>
6
7#include <memory>
8#include <iterator>
9#include <cstdlib>
10#include <cassert>
11#include <iosfwd>
12#include <functional>
13#include <chrono>
14#include <mutex>
15
16#define EFL_EINA_BOOST_MOVABLE_BUT_NOT_COPYABLE(x)
17#define EFL_EINA_BOOST_RV_REF(x) x const&
18
19namespace efl { namespace eina {
20
21struct mutex
22{
23 typedef Eina_Lock* native_handle_type;
24
25 mutex()
26 {
27 ::eina_lock_new(&_mutex);
28 }
29 ~mutex()
30 {
31 ::eina_lock_free(&_mutex);
32 }
33 void lock()
34 {
35 ::Eina_Lock_Result r = ::eina_lock_take(&_mutex);
36 switch(r)
37 {
38 case EINA_LOCK_SUCCEED:
39 return;
40 case EINA_LOCK_DEADLOCK:
41 throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
42 , get_generic_category()));
43 default:
44 throw system_error(get_error_code());
45 }
46 }
47 bool try_lock()
48 {
49 ::Eina_Lock_Result r = ::eina_lock_take_try(&_mutex);
50 switch(r)
51 {
52 case EINA_LOCK_SUCCEED:
53 return true;
54 case EINA_LOCK_FAIL:
55 return false;
56 case EINA_LOCK_DEADLOCK:
57 throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
58 , get_generic_category()));
59 default:
60 throw system_error(get_error_code());
61 }
62 }
63 void unlock()
64 {
65 ::Eina_Lock_Result r = ::eina_lock_release(&_mutex);
66 switch(r)
67 {
68 case EINA_LOCK_SUCCEED:
69 return;
70 case EINA_LOCK_DEADLOCK:
71 throw system_error(error_code(int(eina::errc::resource_deadlock_would_occur)
72 , get_generic_category()));
73 default:
74 throw system_error(get_error_code());
75 }
76 }
77 void debug()
78 {
79 ::eina_lock_debug(&_mutex);
80 }
81 native_handle_type native_handle()
82 {
83 return &_mutex;
84 }
85private:
86 mutex(mutex const&) = delete;
87 mutex& operator=(mutex const&) = delete;
88
89 Eina_Lock _mutex;
90};
91
92using std::lock_guard;
93using std::unique_lock;
94
95struct condition_variable
96{
97 typedef Eina_Condition* native_handle_type;
98
99 condition_variable()
100 {
101 ::eina_condition_new(&_cond, _mutex.native_handle());
102 }
103 ~condition_variable()
104 {
105 ::eina_condition_free(&_cond);
106 }
107
108 void notify_one()
109 {
110 eina::unique_lock<eina::mutex> l(_mutex);
111 Eina_Bool r = eina_condition_signal(&_cond);
112 if(!r)
113 throw eina::system_error(eina::get_error_code());
114 }
115 void notify_all()
116 {
117 eina::unique_lock<eina::mutex> l(_mutex);
118 Eina_Bool r = eina_condition_broadcast(&_cond);
119 if(!r)
120 throw eina::system_error(eina::get_error_code());
121 }
122 template <typename Lock>
123 void wait(Lock& lock)
124 {
125 eina::unique_lock<eina::mutex> l(_mutex);
126 lock.unlock();
127 ::eina_condition_wait(&_cond);
128 lock.lock();
129 }
130 template <typename Lock, typename Predicate>
131 void wait(Lock& lock, Predicate p)
132 {
133 while(!p())
134 wait(lock);
135 }
136 native_handle_type native_handle()
137 {
138 return &_cond;
139 }
140private:
141 condition_variable(condition_variable const&);
142 condition_variable& operator=(condition_variable const&);
143
144 mutex _mutex;
145 Eina_Condition _cond;
146};
147
148struct thread_id
149{
150 thread_id() noexcept
151 : _raw(0u)
152 {
153 }
154 thread_id(Eina_Thread raw)
155 : _raw(raw) {}
156 friend inline bool operator==(thread_id lhs, thread_id rhs)
157 {
158 return lhs._raw == rhs._raw;
159 }
160 friend inline bool operator!=(thread_id lhs, thread_id rhs)
161 {
162 return lhs._raw != rhs._raw;
163 }
164 friend inline bool operator<(thread_id lhs, thread_id rhs)
165 {
166 return std::less<Eina_Thread>()(lhs._raw, rhs._raw);
167 }
168private:
169 Eina_Thread _raw;
170};
171
172inline bool operator<=(thread_id lhs, thread_id rhs)
173{
174 return (lhs == rhs) || lhs < rhs;
175}
176inline bool operator>(thread_id lhs, thread_id rhs)
177{
178 return !(lhs <= rhs);
179}
180inline bool operator>=(thread_id lhs, thread_id rhs)
181{
182 return !(lhs < rhs);
183}
184
185template <typename charT, typename Traits>
186std::basic_ostream<charT, Traits>&
187operator<<(std::basic_ostream<charT, Traits>& out, thread_id id)
188{
189 return out << id._raw;
190}
191
192namespace _detail {
193
194struct arguments
195{
196 Eina_Lock mutex;
197 Eina_Condition condition;
198 bool started;
199 std::function<void()> function;
200};
201
202inline void* create_thread(void* data, Eina_Thread)
203{
204 arguments* args = static_cast<arguments*>(data);
205
206 eina_lock_take(&args->mutex);
207
208 std::function<void()> f = std::move(args->function);
209
210 args->started = true;
211 eina_condition_signal(&args->condition);
212 eina_lock_release(&args->mutex);
213
214 f();
215 return 0;
216}
217
218}
219
220struct thread
221{
222 typedef thread_id id;
223 typedef Eina_Thread native_handle_type;
224
225 thread() noexcept
226 : _joinable(false), _raw(0u)
227 {
228 }
229
230 template <typename F, class ... Args>
231 explicit thread(F&& f, Args&&... args)
232 {
233 _detail::arguments arguments;
234 arguments.started = false;
235 arguments.function = std::bind(f, args...);
236
237 _joinable = true;
238 Eina_Bool r = ::eina_lock_new(&arguments.mutex);
239 if(!r) throw eina::system_error(eina::get_error_code());
240 r = ::eina_condition_new(&arguments.condition, &arguments.mutex);
241 if(!r) throw eina::system_error(eina::get_error_code());
242
243 if(!eina_thread_create
244 (&_raw, ::EINA_THREAD_NORMAL
245 , -1, &eina::_detail::create_thread, &arguments))
246 {
247 eina_condition_free(&arguments.condition);
248 eina_lock_free(&arguments.mutex);
249 throw eina::system_error(eina::get_error_code());
250 }
251 Eina_Lock_Result lr = ::eina_lock_take(&arguments.mutex);
252 if(lr != EINA_LOCK_SUCCEED)
253 throw eina::system_error(eina::get_error_code());
254 while(!arguments.started)
255 {
256 r = eina_condition_wait(&arguments.condition);
257 if(!r) throw eina::system_error(eina::get_error_code());
258 }
259 lr = eina_lock_release(&arguments.mutex);
260 if(lr != EINA_LOCK_SUCCEED)
261 throw eina::system_error(eina::get_error_code());
262
263 eina_condition_free(&arguments.condition);
264 eina_lock_free(&arguments.mutex);
265 }
266
267 thread(thread&& other)
268 : _joinable(other._joinable), _raw(other._raw)
269 {
270 }
271
272 thread& operator=(thread&& other)
273 {
274 _raw = other._raw;
275 _joinable = other._joinable;
276 return *this;
277 }
278
279 ~thread()
280 {
281 assert(!joinable());
282 }
283
284 void swap(thread& other) noexcept
285 {
286 std::swap(_raw, other._raw);
287 }
288 bool joinable() const noexcept
289 {
290 return _joinable;
291 }
292
293 void join()
294 {
295 assert(joinable());
296 ::eina_thread_join(_raw);
297 _joinable = false;
298 }
299
300 void detach()
301 {
302 assert(joinable());
303 _joinable = false;
304 }
305
306 id get_id() const noexcept
307 {
308 return id(_raw);
309 }
310 native_handle_type native_handle() const
311 {
312 return _raw;
313 }
314
315 static unsigned hardware_concurrency() noexcept
316 {
317 return ::eina_cpu_count();
318 }
319private:
320 bool _joinable;
321 Eina_Thread _raw;
322};
323
324inline void swap(thread& lhs, thread& rhs)
325{
326 lhs.swap(rhs);
327}
328
329namespace this_thread {
330
331inline thread::id get_id()
332{
333 return thread::id(eina_thread_self());
334}
335
336inline void yield() {}
337
338template <typename Clock, typename Duration>
339void sleep_until(std::chrono::time_point<Clock, Duration>const& abs_time);
340
341template <typename Rep, typename Period>
342void sleep_for(std::chrono::duration<Rep, Period>const& rel_time);
343}
344
345} }
346
347namespace std {
348
349template <typename T> struct hash;
350template <>
351struct hash< ::efl::eina::thread_id> : hash<unsigned long>
352{};
353
354}
355
356#endif
diff --git a/src/lib/eina_cxx/eina_type_traits.hh b/src/lib/eina_cxx/eina_type_traits.hh
new file mode 100644
index 0000000000..bd22457de3
--- /dev/null
+++ b/src/lib/eina_cxx/eina_type_traits.hh
@@ -0,0 +1,51 @@
1#ifndef _EINA_TYPE_TRAITS_HH
2#define _EINA_TYPE_TRAITS_HH
3
4#include <type_traits>
5
6#include <string>
7#include <vector>
8
9namespace efl { namespace eina {
10
11using std::enable_if;
12using std::is_integral;
13using std::is_pod;
14using std::is_const;
15using std::remove_cv;
16using std::true_type;
17using std::false_type;
18using std::remove_pointer;
19using std::remove_reference;
20
21template <typename T, typename Enable = void>
22struct is_contiguous_iterator : false_type {};
23template <>
24struct is_contiguous_iterator<std::string::const_iterator> : true_type {};
25template <>
26struct is_contiguous_iterator<std::string::iterator> : true_type {};
27template <>
28struct is_contiguous_iterator<std::vector<char>::const_iterator> : true_type {};
29template <>
30struct is_contiguous_iterator<std::vector<char>::iterator> : true_type {};
31
32template <bool, typename T, typename F>
33struct if_c
34{
35 typedef T type;
36};
37
38template <typename T, typename F>
39struct if_c<false, T, F>
40{
41 typedef F type;
42};
43
44template <typename U, typename T, typename F>
45struct if_ : if_c<U::value, T, F>
46{
47};
48
49} }
50
51#endif
diff --git a/src/lib/eina_cxx/eina_value.hh b/src/lib/eina_cxx/eina_value.hh
new file mode 100644
index 0000000000..aee5b853c2
--- /dev/null
+++ b/src/lib/eina_cxx/eina_value.hh
@@ -0,0 +1,371 @@
1#ifndef _EFL_EINA_EINA_VALUE_HH
2#define _EFL_EINA_EINA_VALUE_HH
3
4#include <Eina.h>
5
6#include <eina_stringshare.hh>
7#include <eina_type_traits.hh>
8
9namespace efl { namespace eina {
10
11template <typename T>
12struct _eina_value_traits_base;
13
14template <typename T>
15struct _eina_value_traits_aux;
16
17// Indirection for uint64_t. uint64_t can be a typedef for unsigned
18// long, so we can't specialize on the same template
19template <>
20struct _eina_value_traits_aux<uint64_t>
21{
22 static ::Eina_Value_Type const* value_type()
23 {
24 return EINA_VALUE_TYPE_UINT64;
25 }
26};
27
28template <typename T, typename Enable = void>
29struct _eina_value_traits : _eina_value_traits_aux<T>
30{
31};
32
33template <typename T>
34struct _eina_value_traits_base
35{
36 typedef T type;
37
38 static ::Eina_Value* create()
39 {
40 return eina_value_new(_eina_value_traits<T>::value_type());
41 }
42 static void set_type( ::Eina_Value* v)
43 {
44 eina_value_setup(v, _eina_value_traits<T>::value_type());
45 }
46 static void set( ::Eina_Value* v, type c)
47 {
48 ::eina_value_set(v, c);
49 }
50 static type get( ::Eina_Value* v)
51 {
52 if(_eina_value_traits<T>::value_type() == eina_value_type_get(v))
53 {
54 type vv;
55 if(::eina_value_get(v, &vv))
56 return vv;
57 else
58 throw eina::system_error(eina::get_error_code());
59 }
60 else
61 throw eina::system_error(EINA_ERROR_VALUE_FAILED, eina::eina_error_category());
62 }
63};
64
65template <>
66struct _eina_value_traits<unsigned char>
67 : _eina_value_traits_base<unsigned char>
68{
69 static ::Eina_Value_Type const* value_type()
70 {
71 return EINA_VALUE_TYPE_UCHAR;
72 }
73};
74
75template <>
76struct _eina_value_traits<unsigned short>
77 : _eina_value_traits_base<unsigned short>
78{
79 static ::Eina_Value_Type const* value_type()
80 {
81 return EINA_VALUE_TYPE_USHORT;
82 }
83};
84
85template <>
86struct _eina_value_traits<unsigned int>
87 : _eina_value_traits_base<unsigned int>
88{
89 static ::Eina_Value_Type const* value_type()
90 {
91 return EINA_VALUE_TYPE_UINT;
92 }
93};
94
95template <>
96struct _eina_value_traits<unsigned long>
97 : _eina_value_traits_base<unsigned long>
98{
99 static ::Eina_Value_Type const* value_type()
100 {
101 return EINA_VALUE_TYPE_ULONG;
102 }
103};
104
105template <>
106struct _eina_value_traits<char>
107 : _eina_value_traits_base<char>
108{
109 static ::Eina_Value_Type const* value_type()
110 {
111 return EINA_VALUE_TYPE_CHAR;
112 }
113};
114
115template <>
116struct _eina_value_traits<short>
117 : _eina_value_traits_base<short>
118{
119 static ::Eina_Value_Type const* value_type()
120 {
121 return EINA_VALUE_TYPE_SHORT;
122 }
123};
124
125template <>
126struct _eina_value_traits<int>
127 : _eina_value_traits_base<int>
128{
129 static ::Eina_Value_Type const* value_type()
130 {
131 return EINA_VALUE_TYPE_INT;
132 }
133};
134
135template <>
136struct _eina_value_traits<long>
137 : _eina_value_traits_base<long>
138{
139 static ::Eina_Value_Type const* value_type()
140 {
141 return EINA_VALUE_TYPE_LONG;
142 }
143};
144
145template <>
146struct _eina_value_traits<float>
147 : _eina_value_traits_base<float>
148{
149 static ::Eina_Value_Type const* value_type()
150 {
151 return EINA_VALUE_TYPE_FLOAT;
152 }
153};
154
155template <>
156struct _eina_value_traits<double>
157 : _eina_value_traits_base<double>
158{
159 static ::Eina_Value_Type const* value_type()
160 {
161 return EINA_VALUE_TYPE_DOUBLE;
162 }
163};
164
165template <>
166struct _eina_value_traits<stringshare>
167 : _eina_value_traits_base<stringshare>
168{
169 static ::Eina_Value_Type const* value_type()
170 {
171 return EINA_VALUE_TYPE_STRINGSHARE;
172 }
173 static void set( ::Eina_Value* v, type c)
174 {
175 ::eina_value_set(v, c.data());
176 }
177 static type get( ::Eina_Value* v)
178 {
179 char* c_str;
180 ::eina_value_get(v, &c_str);
181 return stringshare(c_str, steal_stringshare_ref);
182 }
183};
184
185template <>
186struct _eina_value_traits<std::string>
187 : _eina_value_traits_base<std::string>
188{
189 typedef typename _eina_value_traits_base<std::string>::type type;
190 static ::Eina_Value_Type const* value_type()
191 {
192 return EINA_VALUE_TYPE_STRING;
193 }
194 static void set( ::Eina_Value* v, type c)
195 {
196 ::eina_value_set(v, c.c_str());
197 }
198 static type get( ::Eina_Value* v)
199 {
200 char* c_str;
201 ::eina_value_get(v, &c_str);