cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2ab6aac74d75bc07a6ed77993e7b82b2f1d4de55

commit 2ab6aac74d75bc07a6ed77993e7b82b2f1d4de55
Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br>
Date:   Mon Mar 10 12:25:42 2014 +0900

    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<int, efl::eina::malloc_clone_allocator> 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
---
 src/bindings/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 459b635..9174eee 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 <memory>
+#include <cstring>
+#include <cstdlib>
+#include <type_traits>
 
 namespace efl { namespace eina {
 
@@ -64,6 +67,25 @@ struct heap_no_copy_allocator
   }
 };    
 
+struct malloc_clone_allocator
+{
+  template <typename T>
+  static T* allocate_clone(T const& v)
+  {
+    static_assert(std::is_pod<T>::value, "malloc_clone_allocator can only be 
used with POD types");
+    T* p = static_cast<T*>(std::malloc(sizeof(T)));
+    std::memcpy(p, &v, sizeof(T));
+    return p;
+  }
+
+  template <typename T>
+  static void deallocate_clone(T const* p)
+  {
+    static_assert(std::is_pod<T>::value, "malloc_clone_allocator can only be 
used with POD types");
+    std::free(const_cast<T*>(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 dbded3a..d68095e 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<int, efl::eina::malloc_clone_allocator> list1;
+  list1.push_back(5);
+  list1.push_back(10);
+
+  efl::eina::ptr_list<int, efl::eina::malloc_clone_allocator> 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);
 }

-- 


Reply via email to