From 69b8f326d4abf04266850fa0343b7a8592c68281 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 2 Sep 2017 23:20:24 +0200 Subject: [PATCH] [DEV] fork on etk::Function --- etk/Function.hpp | 64 +++++++++++++++++++++++++---------------------- etk/move.hpp | 49 +++++++++++++++++++++++++++++++----- etk/types.hpp | 25 ++++++++++-------- etk/utf8.hpp | 5 ---- lutin_etk-base.py | 3 ++- 5 files changed, 94 insertions(+), 52 deletions(-) diff --git a/etk/Function.hpp b/etk/Function.hpp index a58a94a..3492491 100644 --- a/etk/Function.hpp +++ b/etk/Function.hpp @@ -5,12 +5,14 @@ */ #include +//#include #pragma once namespace etk { template class Function; + template class Function { // function pointer types for the type-erasure behaviors @@ -18,24 +20,23 @@ namespace etk { typedef ETK_TYPE_FUNCTION_RETURN (*invoke_fn_t)(char*, ETK_TYPE_FUNCTION_ARGS&&...); typedef void (*construct_fn_t)(char*, char*); typedef void (*destroy_fn_t)(char*); - // type-aware generic functions for invoking // the specialization of these functions won't be capable with // the above function pointer types, so we need some cast template static ETK_TYPE_FUNCTION_RETURN invoke_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor, ETK_TYPE_FUNCTION_ARGS&&... _args) { - return (*_functor)(std::forward(_args)...); + return (*_functor)(etk::forward(_args)...); } template static void construct_fn(ETK_TYPE_FUNCTION_FUNCTOR* _constructDestination, ETK_TYPE_FUNCTION_FUNCTOR* _constructSource) { // the functor type must be copy-constructible - new (_constructDestination) Functor(*_constructSource); + new (_constructDestination) Function(*_constructSource); } template static void destroy_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor) { - _functor->~Functor(); + _functor->~Function(); } // These pointers are storing behaviors. invoke_fn_t invoke_f; @@ -43,10 +44,10 @@ namespace etk { destroy_fn_t destroy_f; // Erase the type of any functor and store it into a char* // so the storage size should be obtained as well - std::unique_ptr m_dataPointer; + char* m_dataPointer; size_t m_dataSize; public: - function() + Function() : invoke_f(nullptr) , construct_f(nullptr) , destroy_f(nullptr) @@ -56,42 +57,45 @@ namespace etk { // construct from any functor type template - Function(ETK_TYPE_FUNCTION_FUNCTOR _funtor) - // specialize functions and erase their type info by casting - : invoke_f(reinterpret_cast(invoke_fn)) - , construct_f(reinterpret_cast(construct_fn)) - , destroy_f(reinterpret_cast(destroy_fn)) - , m_dataPointer(new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)]) - , m_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR)) - { + Function(ETK_TYPE_FUNCTION_FUNCTOR _functor): + // specialize functions and erase their type info by casting + invoke_f(reinterpret_cast(invoke_fn)), + construct_f(reinterpret_cast(construct_fn)), + destroy_f(reinterpret_cast(destroy_fn)), + m_dataPointer(new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)]), + m_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR)) { // copy the functor to internal storage - this->construct_f(this->m_dataPointer.get(), reinterpret_cast(&_functor)); + construct_f(m_dataPointer, reinterpret_cast(&_functor)); } - // copy constructor - Function(Function const& rhs): - invoke_f(rhs.invoke_f), - construct_f(rhs.construct_f) - destroy_f(rhs.destroy_f), - dataSize(rhs.dataSize) { - if (this->invoke_f) { + Function(Function const& _obj): + invoke_f(_obj.invoke_f), + construct_f(_obj.construct_f), + destroy_f(_obj.destroy_f), + m_dataSize(_obj.m_dataSize) { + if (invoke_f) { // when the source is not a null function, copy its internal functor - this->m_dataPointer.reset(new char[this->m_dataSize]); - this->construct_f(this->m_dataPointer.get(), rhs.m_dataPointer.get()); + delete(m_dataPointer); + m_dataPointer = new char[m_dataSize]; + construct_f(m_dataPointer, _obj.m_dataPointer); } } - ~Function() { if (m_dataPointer != nullptr) { - this->destroy_f(this->m_dataPointer.get()); + destroy_f(m_dataPointer); + delete m_dataPointer; } } - // other constructors, from nullptr, from function pointers - ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS&&... _args) { - return this->invoke_f(this->m_dataPointer.get(), - std::forward(_args)...); + return invoke_f(m_dataPointer, + etk::forward(_args)...); + } + bool operator!= (nullptr_t) const { + return m_dataPointer != nullptr; + } + bool operator== (nullptr_t) const { + return m_dataPointer == nullptr; } }; } diff --git a/etk/move.hpp b/etk/move.hpp index f219da5..4499956 100644 --- a/etk/move.hpp +++ b/etk/move.hpp @@ -8,25 +8,62 @@ namespace etk { template - struct _Remove_reference { + struct RemoveReference { // remove reference typedef ETK_MOVE_TYPE m_type; }; template - struct _Remove_reference { + struct RemoveReference { // remove reference typedef ETK_MOVE_TYPE m_type; }; template - struct _Remove_reference { + struct RemoveReference { // remove rvalue reference typedef ETK_MOVE_TYPE m_type; }; template inline - typename etk::_Remove_reference::m_type&& move(ETK_MOVE_TYPE&& _obj) { + typename etk::RemoveReference::m_type&& move(ETK_MOVE_TYPE&& _obj) { // forward _Arg as movable - return ((typename etk::_Remove_reference::m_type&&)_obj); + return ((typename etk::RemoveReference::m_type&&)_obj); + } + template + inline void swap(ETK_SWAP_TYPE& _obj1, ETK_SWAP_TYPE& _obj2) { + ETK_SWAP_TYPE tmp = etk::move(_obj1); + _obj1 = etk::move(_obj2); + _obj2 = etk::move(tmp); + } + + template + struct integralConstant { + static constexpr ETK_TYPE value = v; + typedef ETK_TYPE typeValue; + // using injected-class-name + typedef integralConstant type; + constexpr operator typeValue() const noexcept { + return value; + } + constexpr typeValue operator()() const noexcept { + return value; + } + }; + + typedef etk::integralConstant typeTrue; + typedef etk::integralConstant typeFalse; + + template + struct isLeftValueReference : etk::typeFalse {}; + template + struct isLeftValueReference : etk::typeTrue {}; + + template + inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference::m_type& _obj) noexcept { + return static_cast(_obj); + } + template + inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference::m_type&& _obj) noexcept { + static_assert(!etk::isLeftValueReference::type, "Can not forward an rvalue as an lvalue."); + return static_cast(_obj); } - } diff --git a/etk/types.hpp b/etk/types.hpp index 393e206..3058069 100644 --- a/etk/types.hpp +++ b/etk/types.hpp @@ -4,15 +4,18 @@ * @license MPL v2.0 (see license file) */ #pragma once -#include -#include -#include -#include -#include -// defien type : uintXX_t and intXX_t -#define __STDC_LIMIT_MACROS -// note in android include the macro of min max are overwitten -#include +extern "C" { + #include + #include + #include + #include + #include + // defien type : uintXX_t and intXX_t + #define __STDC_LIMIT_MACROS + // note in android include the macro of min max are overwitten + #include + #include +} // in case of android error ... #ifdef __TARGET_OS__Android #if __ANDROID_BOARD_ID__ <= 20 @@ -42,7 +45,9 @@ #endif #ifndef _WIN32 - #include + extern "C" { + #include + } #ifndef _MATH_H_MATHDEF //! @brief Generate a basic type for floating point unit selection (not finished) using float_t = float; diff --git a/etk/utf8.hpp b/etk/utf8.hpp index b8aa4ac..25cbe3c 100644 --- a/etk/utf8.hpp +++ b/etk/utf8.hpp @@ -8,11 +8,6 @@ #include #include #include -#include -#include -#include -#include -#include #include namespace etk { diff --git a/lutin_etk-base.py b/lutin_etk-base.py index e6064ca..1abc32f 100644 --- a/lutin_etk-base.py +++ b/lutin_etk-base.py @@ -33,6 +33,7 @@ def configure(target, my_module): 'etk/utf8.cpp', 'etk/stdTools.cpp', 'etk/Stream.cpp', + 'etk/Function.cpp', ]) my_module.add_header_file([ @@ -47,6 +48,7 @@ def configure(target, my_module): 'etk/Pair.hpp', 'etk/Map.hpp', 'etk/move.hpp', + 'etk/Function.hpp', ]) # build in C++ mode @@ -56,7 +58,6 @@ def configure(target, my_module): 'c', 'm', "pthread", - "cxx", ]) if "Android" in target.get_type():