[DEV] fork on etk::Function
This commit is contained in:
parent
4abbcad222
commit
69b8f326d4
@ -5,12 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
|
//#include <ememory/UniquePtr.hpp>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
template <typename ETK_TYPE_FUNCTION>
|
template <typename ETK_TYPE_FUNCTION>
|
||||||
class Function;
|
class Function;
|
||||||
|
|
||||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||||
class Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
|
class Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
|
||||||
// function pointer types for the type-erasure behaviors
|
// 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 ETK_TYPE_FUNCTION_RETURN (*invoke_fn_t)(char*, ETK_TYPE_FUNCTION_ARGS&&...);
|
||||||
typedef void (*construct_fn_t)(char*, char*);
|
typedef void (*construct_fn_t)(char*, char*);
|
||||||
typedef void (*destroy_fn_t)(char*);
|
typedef void (*destroy_fn_t)(char*);
|
||||||
|
|
||||||
// type-aware generic functions for invoking
|
// type-aware generic functions for invoking
|
||||||
// the specialization of these functions won't be capable with
|
// the specialization of these functions won't be capable with
|
||||||
// the above function pointer types, so we need some cast
|
// the above function pointer types, so we need some cast
|
||||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||||
static ETK_TYPE_FUNCTION_RETURN invoke_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor,
|
static ETK_TYPE_FUNCTION_RETURN invoke_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor,
|
||||||
ETK_TYPE_FUNCTION_ARGS&&... _args) {
|
ETK_TYPE_FUNCTION_ARGS&&... _args) {
|
||||||
return (*_functor)(std::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
return (*_functor)(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||||
}
|
}
|
||||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||||
static void construct_fn(ETK_TYPE_FUNCTION_FUNCTOR* _constructDestination,
|
static void construct_fn(ETK_TYPE_FUNCTION_FUNCTOR* _constructDestination,
|
||||||
ETK_TYPE_FUNCTION_FUNCTOR* _constructSource) {
|
ETK_TYPE_FUNCTION_FUNCTOR* _constructSource) {
|
||||||
// the functor type must be copy-constructible
|
// the functor type must be copy-constructible
|
||||||
new (_constructDestination) Functor(*_constructSource);
|
new (_constructDestination) Function(*_constructSource);
|
||||||
}
|
}
|
||||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||||
static void destroy_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor) {
|
static void destroy_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor) {
|
||||||
_functor->~Functor();
|
_functor->~Function();
|
||||||
}
|
}
|
||||||
// These pointers are storing behaviors.
|
// These pointers are storing behaviors.
|
||||||
invoke_fn_t invoke_f;
|
invoke_fn_t invoke_f;
|
||||||
@ -43,10 +44,10 @@ namespace etk {
|
|||||||
destroy_fn_t destroy_f;
|
destroy_fn_t destroy_f;
|
||||||
// Erase the type of any functor and store it into a char*
|
// Erase the type of any functor and store it into a char*
|
||||||
// so the storage size should be obtained as well
|
// so the storage size should be obtained as well
|
||||||
std::unique_ptr<char[]> m_dataPointer;
|
char* m_dataPointer;
|
||||||
size_t m_dataSize;
|
size_t m_dataSize;
|
||||||
public:
|
public:
|
||||||
function()
|
Function()
|
||||||
: invoke_f(nullptr)
|
: invoke_f(nullptr)
|
||||||
, construct_f(nullptr)
|
, construct_f(nullptr)
|
||||||
, destroy_f(nullptr)
|
, destroy_f(nullptr)
|
||||||
@ -56,42 +57,45 @@ namespace etk {
|
|||||||
|
|
||||||
// construct from any functor type
|
// construct from any functor type
|
||||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||||
Function(ETK_TYPE_FUNCTION_FUNCTOR _funtor)
|
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||||
// specialize functions and erase their type info by casting
|
// specialize functions and erase their type info by casting
|
||||||
: invoke_f(reinterpret_cast<invoke_fn_t>(invoke_fn<ETK_TYPE_FUNCTION_FUNCTOR>))
|
invoke_f(reinterpret_cast<invoke_fn_t>(invoke_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||||
, construct_f(reinterpret_cast<construct_fn_t>(construct_fn<ETK_TYPE_FUNCTION_FUNCTOR>))
|
construct_f(reinterpret_cast<construct_fn_t>(construct_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||||
, destroy_f(reinterpret_cast<destroy_fn_t>(destroy_fn<ETK_TYPE_FUNCTION_FUNCTOR>))
|
destroy_f(reinterpret_cast<destroy_fn_t>(destroy_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||||
, m_dataPointer(new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)])
|
m_dataPointer(new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)]),
|
||||||
, m_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR))
|
m_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR)) {
|
||||||
{
|
|
||||||
// copy the functor to internal storage
|
// copy the functor to internal storage
|
||||||
this->construct_f(this->m_dataPointer.get(), reinterpret_cast<char*>(&_functor));
|
construct_f(m_dataPointer, reinterpret_cast<char*>(&_functor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy constructor
|
// copy constructor
|
||||||
Function(Function const& rhs):
|
Function(Function const& _obj):
|
||||||
invoke_f(rhs.invoke_f),
|
invoke_f(_obj.invoke_f),
|
||||||
construct_f(rhs.construct_f)
|
construct_f(_obj.construct_f),
|
||||||
destroy_f(rhs.destroy_f),
|
destroy_f(_obj.destroy_f),
|
||||||
dataSize(rhs.dataSize) {
|
m_dataSize(_obj.m_dataSize) {
|
||||||
if (this->invoke_f) {
|
if (invoke_f) {
|
||||||
// when the source is not a null function, copy its internal functor
|
// when the source is not a null function, copy its internal functor
|
||||||
this->m_dataPointer.reset(new char[this->m_dataSize]);
|
delete(m_dataPointer);
|
||||||
this->construct_f(this->m_dataPointer.get(), rhs.m_dataPointer.get());
|
m_dataPointer = new char[m_dataSize];
|
||||||
|
construct_f(m_dataPointer, _obj.m_dataPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Function() {
|
~Function() {
|
||||||
if (m_dataPointer != nullptr) {
|
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
|
// other constructors, from nullptr, from function pointers
|
||||||
|
|
||||||
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS&&... _args) {
|
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS&&... _args) {
|
||||||
return this->invoke_f(this->m_dataPointer.get(),
|
return invoke_f(m_dataPointer,
|
||||||
std::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||||
|
}
|
||||||
|
bool operator!= (nullptr_t) const {
|
||||||
|
return m_dataPointer != nullptr;
|
||||||
|
}
|
||||||
|
bool operator== (nullptr_t) const {
|
||||||
|
return m_dataPointer == nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
49
etk/move.hpp
49
etk/move.hpp
@ -8,25 +8,62 @@
|
|||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
template<class ETK_MOVE_TYPE>
|
template<class ETK_MOVE_TYPE>
|
||||||
struct _Remove_reference {
|
struct RemoveReference {
|
||||||
// remove reference
|
// remove reference
|
||||||
typedef ETK_MOVE_TYPE m_type;
|
typedef ETK_MOVE_TYPE m_type;
|
||||||
};
|
};
|
||||||
template<class ETK_MOVE_TYPE>
|
template<class ETK_MOVE_TYPE>
|
||||||
struct _Remove_reference<ETK_MOVE_TYPE&> {
|
struct RemoveReference<ETK_MOVE_TYPE&> {
|
||||||
// remove reference
|
// remove reference
|
||||||
typedef ETK_MOVE_TYPE m_type;
|
typedef ETK_MOVE_TYPE m_type;
|
||||||
};
|
};
|
||||||
template<class ETK_MOVE_TYPE>
|
template<class ETK_MOVE_TYPE>
|
||||||
struct _Remove_reference<ETK_MOVE_TYPE&&> {
|
struct RemoveReference<ETK_MOVE_TYPE&&> {
|
||||||
// remove rvalue reference
|
// remove rvalue reference
|
||||||
typedef ETK_MOVE_TYPE m_type;
|
typedef ETK_MOVE_TYPE m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class ETK_MOVE_TYPE> inline
|
template<class ETK_MOVE_TYPE> inline
|
||||||
typename etk::_Remove_reference<ETK_MOVE_TYPE>::m_type&& move(ETK_MOVE_TYPE&& _obj) {
|
typename etk::RemoveReference<ETK_MOVE_TYPE>::m_type&& move(ETK_MOVE_TYPE&& _obj) {
|
||||||
// forward _Arg as movable
|
// forward _Arg as movable
|
||||||
return ((typename etk::_Remove_reference<ETK_MOVE_TYPE>::m_type&&)_obj);
|
return ((typename etk::RemoveReference<ETK_MOVE_TYPE>::m_type&&)_obj);
|
||||||
|
}
|
||||||
|
template<typename ETK_SWAP_TYPE>
|
||||||
|
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<class ETK_TYPE, ETK_TYPE v>
|
||||||
|
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<bool, true> typeTrue;
|
||||||
|
typedef etk::integralConstant<bool, false> typeFalse;
|
||||||
|
|
||||||
|
template<class ETK_TYPE>
|
||||||
|
struct isLeftValueReference : etk::typeFalse {};
|
||||||
|
template<class ETK_TYPE>
|
||||||
|
struct isLeftValueReference<ETK_TYPE&> : etk::typeTrue {};
|
||||||
|
|
||||||
|
template <class ETK_FORWARD_TYPE>
|
||||||
|
inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type& _obj) noexcept {
|
||||||
|
return static_cast<ETK_FORWARD_TYPE&&>(_obj);
|
||||||
|
}
|
||||||
|
template <class ETK_FORWARD_TYPE>
|
||||||
|
inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type&& _obj) noexcept {
|
||||||
|
static_assert(!etk::isLeftValueReference<ETK_FORWARD_TYPE>::type, "Can not forward an rvalue as an lvalue.");
|
||||||
|
return static_cast<ETK_FORWARD_TYPE&&>(_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,18 @@
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdlib>
|
extern "C" {
|
||||||
#include <cstdio>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdio.h>
|
||||||
#include <cstring>
|
#include <stdarg.h>
|
||||||
#include <cassert>
|
#include <string.h>
|
||||||
// defien type : uintXX_t and intXX_t
|
#include <assert.h>
|
||||||
#define __STDC_LIMIT_MACROS
|
// defien type : uintXX_t and intXX_t
|
||||||
// note in android include the macro of min max are overwitten
|
#define __STDC_LIMIT_MACROS
|
||||||
#include <cstdint>
|
// note in android include the macro of min max are overwitten
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
}
|
||||||
// in case of android error ...
|
// in case of android error ...
|
||||||
#ifdef __TARGET_OS__Android
|
#ifdef __TARGET_OS__Android
|
||||||
#if __ANDROID_BOARD_ID__ <= 20
|
#if __ANDROID_BOARD_ID__ <= 20
|
||||||
@ -42,7 +45,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <cmath>
|
extern "C" {
|
||||||
|
#include <math.h>
|
||||||
|
}
|
||||||
#ifndef _MATH_H_MATHDEF
|
#ifndef _MATH_H_MATHDEF
|
||||||
//! @brief Generate a basic type for floating point unit selection (not finished)
|
//! @brief Generate a basic type for floating point unit selection (not finished)
|
||||||
using float_t = float;
|
using float_t = float;
|
||||||
|
@ -8,11 +8,6 @@
|
|||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
#include <etk/String.hpp>
|
#include <etk/String.hpp>
|
||||||
#include <etk/Vector.hpp>
|
#include <etk/Vector.hpp>
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <chrono>
|
|
||||||
#include <etk/stdTools.hpp>
|
#include <etk/stdTools.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
|
@ -33,6 +33,7 @@ def configure(target, my_module):
|
|||||||
'etk/utf8.cpp',
|
'etk/utf8.cpp',
|
||||||
'etk/stdTools.cpp',
|
'etk/stdTools.cpp',
|
||||||
'etk/Stream.cpp',
|
'etk/Stream.cpp',
|
||||||
|
'etk/Function.cpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
my_module.add_header_file([
|
my_module.add_header_file([
|
||||||
@ -47,6 +48,7 @@ def configure(target, my_module):
|
|||||||
'etk/Pair.hpp',
|
'etk/Pair.hpp',
|
||||||
'etk/Map.hpp',
|
'etk/Map.hpp',
|
||||||
'etk/move.hpp',
|
'etk/move.hpp',
|
||||||
|
'etk/Function.hpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
# build in C++ mode
|
# build in C++ mode
|
||||||
@ -56,7 +58,6 @@ def configure(target, my_module):
|
|||||||
'c',
|
'c',
|
||||||
'm',
|
'm',
|
||||||
"pthread",
|
"pthread",
|
||||||
"cxx",
|
|
||||||
])
|
])
|
||||||
|
|
||||||
if "Android" in target.get_type():
|
if "Android" in target.get_type():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user