From 2ab6aac74d75bc07a6ed77993e7b82b2f1d4de55 Mon Sep 17 00:00:00 2001 From: Felipe Magno de Almeida Date: Mon, 10 Mar 2014 12:25:42 +0900 Subject: [PATCH] eina-cxx: Added malloc_clone_allocator to use with POD's when wrapping Eina C structures Summary: Added efl::eina::malloc_clone_allocator to be used with ptr_* data structures for wrapping structures allocated by EFL in C. This allows for example: void foo(Eina_List* l) { efl::eina::ptr_list list(l); } If the standard efl::eina::heap_no_clone_allocator is used, the deallocation code uses C++ delete operator, which causes undefined behavior because the allocation was originally done with malloc. Reviewers: cedric CC: savio, cedric Differential Revision: https://phab.enlightenment.org/D614 --- .../eina_cxx/eina_clone_allocators.hh | 22 +++++++++++++++++++ src/tests/eina_cxx/eina_cxx_test_ptrlist.cc | 14 ++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/bindings/eina_cxx/eina_clone_allocators.hh b/src/bindings/eina_cxx/eina_clone_allocators.hh index 459b6356cd..9174eee609 100644 --- a/src/bindings/eina_cxx/eina_clone_allocators.hh +++ b/src/bindings/eina_cxx/eina_clone_allocators.hh @@ -2,6 +2,9 @@ #define EINA_CLONE_ALLOCATORS_HH_ #include +#include +#include +#include namespace efl { namespace eina { @@ -64,6 +67,25 @@ struct heap_no_copy_allocator } }; +struct malloc_clone_allocator +{ + template + static T* allocate_clone(T const& v) + { + static_assert(std::is_pod::value, "malloc_clone_allocator can only be used with POD types"); + T* p = static_cast(std::malloc(sizeof(T))); + std::memcpy(p, &v, sizeof(T)); + return p; + } + + template + static void deallocate_clone(T const* p) + { + static_assert(std::is_pod::value, "malloc_clone_allocator can only be used with POD types"); + std::free(const_cast(p)); + } +}; + } } #endif diff --git a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc index dbded3ac46..d68095e45e 100644 --- a/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc +++ b/src/tests/eina_cxx/eina_cxx_test_ptrlist.cc @@ -128,6 +128,19 @@ START_TEST(eina_cxx_ptrlist_insert) } END_TEST + +START_TEST(eina_cxx_ptrlist_malloc_clone_allocator) +{ + efl::eina::eina_init eina_init; + + efl::eina::ptr_list list1; + list1.push_back(5); + list1.push_back(10); + + efl::eina::ptr_list list2 = list1; +} +END_TEST + START_TEST(eina_cxx_ptrlist_constructors) { efl::eina::eina_init eina_init; @@ -240,4 +253,5 @@ eina_test_ptrlist(TCase* tc) tcase_add_test(tc, eina_cxx_ptrlist_constructors); tcase_add_test(tc, eina_cxx_ptrlist_erase); tcase_add_test(tc, eina_cxx_ptrlist_range); + tcase_add_test(tc, eina_cxx_ptrlist_malloc_clone_allocator); }