[DEV] new etk::Function is now correct
This commit is contained in:
parent
a19a120987
commit
5a245687f6
@ -110,6 +110,9 @@ void etest::init(int32_t _argc, const char** _argv) {
|
||||
} else if (data == "--etest-list") {
|
||||
listAllTest();
|
||||
exit(0);
|
||||
} else if (data == "--etest-filter=") {
|
||||
ETEST_PRINT("Missing data in the filter list...");
|
||||
exit(0);
|
||||
} else if (data.startWith("--etest-filter=") == true) {
|
||||
etk::String filter = &data[15];
|
||||
ETEST_PRINT(" Filter: " << filter);
|
||||
@ -199,7 +202,7 @@ int32_t etest::runAllTest() {
|
||||
}
|
||||
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":");
|
||||
echrono::Steady ticGroup = echrono::Steady::now();
|
||||
for (auto &it: getListOfTest()) {
|
||||
for (auto &it: runList) {
|
||||
if (it->getTestGroup() != itGroup) {
|
||||
continue;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ namespace etest {
|
||||
|
||||
#define EXPECT_EQ(element, result) \
|
||||
do { \
|
||||
bool ETEST_VARIABLE_TMP_res = (element == result); \
|
||||
bool ETEST_VARIABLE_TMP_res = ((element) == (result)); \
|
||||
if (etest::g_currentTest == nullptr) { \
|
||||
ETEST_CRITICAL("Not in a test"); \
|
||||
} else { \
|
||||
@ -166,7 +166,7 @@ namespace etest {
|
||||
|
||||
#define EXPECT_NE(element, result) \
|
||||
do { \
|
||||
bool ETEST_VARIABLE_TMP_res = (element != result); \
|
||||
bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \
|
||||
if (etest::g_currentTest == nullptr) { \
|
||||
ETEST_CRITICAL("Not in a test"); \
|
||||
} else { \
|
||||
|
@ -10,8 +10,6 @@
|
||||
#include <etk/debug.hpp>
|
||||
#include <etk/stdTools.hpp>
|
||||
#include <etk/String.hpp>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
class ColorList {
|
||||
public:
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include <etk/String.hpp>
|
||||
#include <etk/UString.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
namespace etk {
|
||||
/**
|
||||
|
299
etk/Function.hpp
299
etk/Function.hpp
@ -1,18 +1,22 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <etk/types.hpp>
|
||||
//#include <ememory/UniquePtr.hpp>
|
||||
#include <etk/String.hpp>
|
||||
|
||||
//#define ETK_FUNCTION_ENABLE_NEW
|
||||
// TO facilitate debug when have a problem ...
|
||||
#define ETK_FUNCTION_DEBUG(...) do {} while(false)
|
||||
//#define ETK_FUNCTION_DEBUG printf
|
||||
|
||||
namespace etk {
|
||||
template <typename ETK_TYPE_FUNCTOR, typename ETK_TYPE_FUNCTION>
|
||||
class FunctionPrivateLambda;
|
||||
template <typename ETK_TYPE_FUNCTION>
|
||||
class FunctionPrivateSpecific;
|
||||
class FunctionPrivateFunction;
|
||||
template <typename ETK_TYPE_FUNCTION>
|
||||
class FunctionPrivate;
|
||||
|
||||
@ -22,241 +26,170 @@ namespace etk {
|
||||
virtual ~FunctionPrivate() {
|
||||
|
||||
}
|
||||
// other constructors, from nullptr, from function pointers
|
||||
virtual ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const = 0;
|
||||
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* copy() {
|
||||
virtual FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* copy() {
|
||||
ETK_FUNCTION_DEBUG(" COPY NULLPTR \n");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
class FunctionPrivateSpecific<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>:
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR, typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
class FunctionPrivateLambda<ETK_TYPE_FUNCTION_FUNCTOR, ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>:
|
||||
public FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
|
||||
private:
|
||||
// function pointer types for the type-erasure behaviors
|
||||
// all these char* parameters are actually casted from some functor type
|
||||
typedef ETK_TYPE_FUNCTION_RETURN (*invoke_fn_t)(void*, ETK_TYPE_FUNCTION_ARGS&&...);
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
typedef void* (*construct_fn_t)();
|
||||
#endif
|
||||
typedef void (*destroy_fn_t)(void*);
|
||||
// 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 <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
static ETK_TYPE_FUNCTION_RETURN invoke_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor,
|
||||
ETK_TYPE_FUNCTION_ARGS&&... _args) {
|
||||
return (*_functor)(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||
}
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
static void* construct_fn() {
|
||||
// the functor type must be copy-constructible
|
||||
return new ETK_TYPE_FUNCTION_FUNCTOR();
|
||||
}
|
||||
#endif
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
static void destroy_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor) {
|
||||
_functor->~ETK_TYPE_FUNCTION_FUNCTOR();
|
||||
}
|
||||
// These pointers are storing behaviors.
|
||||
invoke_fn_t invoke_f;
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
construct_fn_t construct_f;
|
||||
#endif
|
||||
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
|
||||
void* m_dataPointer;
|
||||
ETK_TYPE_FUNCTION_FUNCTOR m_dataPointer;
|
||||
public:
|
||||
FunctionPrivateSpecific():
|
||||
invoke_f(nullptr),
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
construct_f(nullptr),
|
||||
#endif
|
||||
destroy_f(nullptr),
|
||||
m_dataPointer(nullptr) {
|
||||
|
||||
FunctionPrivateLambda(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||
m_dataPointer(_functor) {
|
||||
ETK_FUNCTION_DEBUG(" NEW FunctionPrivateLambda \n");
|
||||
}
|
||||
FunctionPrivateSpecific(etk::NullPtr):
|
||||
invoke_f(nullptr),
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
construct_f(nullptr),
|
||||
#endif
|
||||
destroy_f(nullptr),
|
||||
m_dataPointer(nullptr) {
|
||||
|
||||
}
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
// construct from any functor type
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
FunctionPrivateSpecific(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||
// specialize functions and erase their type info by casting
|
||||
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>)),
|
||||
destroy_f(reinterpret_cast<destroy_fn_t>(destroy_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||
m_dataPointer(nullptr) {
|
||||
m_dataPointer = construct_f();
|
||||
}
|
||||
// copy constructor
|
||||
/*
|
||||
FunctionPrivateSpecific(const FunctionPrivateSpecific& _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
|
||||
delete(m_dataPointer);
|
||||
m_dataPointer = new char[m_dataSize];
|
||||
construct_f(m_dataPointer, _obj.m_dataPointer);
|
||||
}
|
||||
FunctionPrivateLambda(const ETK_TYPE_FUNCTION_FUNCTOR& _functor):
|
||||
m_dataPointer(_functor) {
|
||||
ETK_FUNCTION_DEBUG(" NEW FunctionPrivateLambda \n");
|
||||
}
|
||||
*/
|
||||
#else
|
||||
// move from any functor type
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
FunctionPrivateSpecific(ETK_TYPE_FUNCTION_FUNCTOR&& _functor):
|
||||
// specialize functions and erase their type info by casting
|
||||
invoke_f(reinterpret_cast<invoke_fn_t>(invoke_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
construct_f(reinterpret_cast<construct_fn_t>(construct_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||
#endif
|
||||
destroy_f(reinterpret_cast<destroy_fn_t>(destroy_fn<ETK_TYPE_FUNCTION_FUNCTOR>)),
|
||||
m_dataPointer(nullptr) {
|
||||
m_dataPointer = etk::move(_functor);
|
||||
}
|
||||
~FunctionPrivateLambda() {
|
||||
|
||||
#endif
|
||||
~FunctionPrivateSpecific() {
|
||||
if (m_dataPointer != nullptr) {
|
||||
destroy_f(m_dataPointer);
|
||||
m_dataPointer = nullptr;
|
||||
}
|
||||
}
|
||||
// other constructors, from nullptr, from function pointers
|
||||
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const {
|
||||
return invoke_f(m_dataPointer,
|
||||
etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||
return m_dataPointer(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||
}
|
||||
|
||||
bool operator!= (etk::NullPtr) const {
|
||||
return m_dataPointer != nullptr;
|
||||
}
|
||||
bool operator== (etk::NullPtr) const {
|
||||
return m_dataPointer == nullptr;
|
||||
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* copy() {
|
||||
ETK_FUNCTION_DEBUG(" COPY FunctionPrivateLambda \n");
|
||||
return new FunctionPrivateLambda(m_dataPointer);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ETK_TYPE_FUNCTION>
|
||||
class Function;
|
||||
|
||||
extern uint32_t MM___pppppp;
|
||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
class Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
|
||||
private:
|
||||
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* m_pointerPrivate;
|
||||
|
||||
uint32_t m_pppppp;
|
||||
public:
|
||||
Function():
|
||||
m_pointerPrivate(nullptr) {
|
||||
|
||||
m_pppppp = MM___pppppp++;
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function 1 \n", m_pppppp, (uint64_t)this);
|
||||
}
|
||||
Function(etk::NullPtr):
|
||||
Function(const etk::NullPtr&):
|
||||
m_pointerPrivate(nullptr) {
|
||||
|
||||
m_pppppp = MM___pppppp++;
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function 2\n", m_pppppp, (uint64_t)this);
|
||||
}
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
// construct from any functor type
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||
m_pointerPrivate(new FunctionPrivateSpecific<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>(_functor)) {
|
||||
|
||||
}
|
||||
// copy constructor
|
||||
Function(const Function& _obj):
|
||||
m_pointerPrivate(nullptr) {
|
||||
m_pppppp = MM___pppppp++;
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function (copy constructor) ---------------------- [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
if (_obj.m_pointerPrivate != nullptr) {
|
||||
m_pointerPrivate = _obj.m_pointerPrivate->copy();
|
||||
}
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function (copy constructor) ------- (done) ------- [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
}
|
||||
#else
|
||||
// construct from any functor type
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
||||
Function(ETK_TYPE_FUNCTION_FUNCTOR&& _functor):
|
||||
m_pointerPrivate(new FunctionPrivateSpecific<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>(_functor)) {
|
||||
|
||||
}
|
||||
#endif
|
||||
// copy constructor
|
||||
Function(Function&& _obj):
|
||||
m_pointerPrivate(_obj.m_pointerPrivate) {
|
||||
_obj.m_pointerPrivate = nullptr;
|
||||
m_pointerPrivate(nullptr) {
|
||||
m_pppppp = MM___pppppp++;
|
||||
ETK_FUNCTION_DEBUG("[%d] new Function 2\n", m_pppppp);
|
||||
_obj.swap(*this);
|
||||
ETK_FUNCTION_DEBUG("[%d] new Function 2 (done)\n", m_pppppp);
|
||||
}
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR,
|
||||
typename etk::EnableIf< !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,Function>::value
|
||||
&& !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,etk::NullPtr>::value, int
|
||||
>::type = 0
|
||||
>
|
||||
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||
m_pointerPrivate(nullptr) {
|
||||
m_pppppp = MM___pppppp++;
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function 4 \n", m_pppppp, (uint64_t)this);
|
||||
m_pointerPrivate = new FunctionPrivateLambda<ETK_TYPE_FUNCTION_FUNCTOR, ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>(_functor);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] new Function 4 (done)\n", m_pppppp, (uint64_t)this);
|
||||
}
|
||||
~Function() {
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] DELETE Function \n", m_pppppp, (uint64_t)this);
|
||||
delete m_pointerPrivate;
|
||||
m_pointerPrivate = nullptr;
|
||||
}
|
||||
// other constructors, from nullptr, from function pointers
|
||||
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const {
|
||||
if (m_pointerPrivate == nullptr) {
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function (With nullptr !!! ==> must assert ...)\n", m_pppppp, (uint64_t)this);
|
||||
throw;
|
||||
}
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] call Function \n", m_pppppp, (uint64_t)this);
|
||||
return (*m_pointerPrivate)(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||
}
|
||||
Function& operator= (const Function& _obj){
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(set) Function [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
Function(_obj).swap(*this);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(set) Function [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
return *this;
|
||||
}
|
||||
Function& operator= (Function&& _obj){
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(move) Function [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
Function(etk::move(_obj)).swap(*this);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator=(move) Function [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)&_obj);
|
||||
return *this;
|
||||
}
|
||||
Function& operator= (etk::NullPtr _obj) {
|
||||
delete m_pointerPrivate;
|
||||
m_pointerPrivate = nullptr;
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = nullptr 0X%lx\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(Function& _obj) {
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] swap [%d=0X%lx]\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)_obj);
|
||||
etk::swap(m_pointerPrivate, _obj.m_pointerPrivate);
|
||||
etk::swap(m_pppppp, _obj.m_pppppp);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] swap [%d=0X%lx] (done)\n", m_pppppp, (uint64_t)this, _obj.m_pppppp, (uint64_t)_obj);
|
||||
}
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR,
|
||||
typename etk::EnableIf< !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,Function>::value
|
||||
&& !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,etk::NullPtr>::value, int
|
||||
>::type = 0
|
||||
>
|
||||
Function& operator= (ETK_TYPE_FUNCTION_FUNCTOR&& _functor){
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = FUNCTOR \n", m_pppppp, (uint64_t)this);
|
||||
Function(etk::forward<ETK_TYPE_FUNCTION_FUNCTOR>(_functor)).swap(*this);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = FUNCTOR (done)\n", m_pppppp, (uint64_t)this);
|
||||
return *this;
|
||||
}
|
||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR,
|
||||
typename etk::EnableIf< !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,Function>::value
|
||||
&& !etk::IsSame<ETK_TYPE_FUNCTION_FUNCTOR,etk::NullPtr>::value, int
|
||||
>::type = 0
|
||||
>
|
||||
Function& operator= (const ETK_TYPE_FUNCTION_FUNCTOR& _functor){
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = const FUNCTOR& \n", m_pppppp, (uint64_t)this);
|
||||
Function(_functor).swap(*this);
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator = const FUNCTOR& (done)\n", m_pppppp, (uint64_t)this);
|
||||
return *this;
|
||||
}
|
||||
operator bool() const {
|
||||
return m_pointerPrivate != nullptr;
|
||||
}
|
||||
bool operator!= (etk::NullPtr) const {
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator != nullptr ==> 0X%lx %s\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate, (m_pointerPrivate != nullptr)?"true":"false");
|
||||
return m_pointerPrivate != nullptr;
|
||||
}
|
||||
bool operator== (etk::NullPtr) const {
|
||||
ETK_FUNCTION_DEBUG("[%d=0X%lx] operator == nullptr ==> 0X%lx %s\n", m_pppppp, (uint64_t)this, (uint64_t)m_pointerPrivate, (m_pointerPrivate == nullptr)?"true":"false");
|
||||
return m_pointerPrivate == nullptr;
|
||||
}
|
||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
||||
Function& operator= (const Function& _obj) {
|
||||
delete m_pointerPrivate;
|
||||
m_pointerPrivate = nullptr;
|
||||
if (_obj.m_pointerPrivate != nullptr) {
|
||||
m_pointerPrivate = _obj.m_pointerPrivate->copy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
Function& operator= (Function&& _obj) {
|
||||
delete m_pointerPrivate;
|
||||
m_pointerPrivate = _obj.m_pointerPrivate;
|
||||
_obj.m_pointerPrivate = nullptr;
|
||||
return *this;
|
||||
etk::String toString() const {
|
||||
etk::String out = "etk::Function<..(...)>(@";
|
||||
out += etk::toString((uint64_t)m_pointerPrivate);
|
||||
out += ")";
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! @not_in_doc
|
||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
etk::Stream& operator <<(etk::Stream& _os, const etk::Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>& _obj) {
|
||||
_os << _obj.toString();
|
||||
return _os;
|
||||
}
|
||||
|
||||
/*
|
||||
// examples
|
||||
int main()
|
||||
{
|
||||
int i = 0;
|
||||
auto fn = [i](etk::String const& s) mutable
|
||||
{
|
||||
std::cout << ++i << ". " << s << std::endl;
|
||||
};
|
||||
fn("first"); // 1. first
|
||||
fn("second"); // 2. second
|
||||
|
||||
// construct from lambda
|
||||
::function<void(std::string const&)> f(fn);
|
||||
f("third"); // 3. third
|
||||
|
||||
// copy from another function
|
||||
::function<void(std::string const&)> g(f);
|
||||
f("forth - f"); // 4. forth - f
|
||||
g("forth - g"); // 4. forth - g
|
||||
|
||||
// capture and copy non-trivial types like std::string
|
||||
std::string x("xxxx");
|
||||
::function<void()> h([x]() { std::cout << x << std::endl; });
|
||||
h();
|
||||
|
||||
::function<void()> k(h);
|
||||
k();
|
||||
return 0;
|
||||
}
|
||||
*/
|
79
etk/NullPtr.hpp
Normal file
79
etk/NullPtr.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace etk {
|
||||
class NullPtr {
|
||||
public:
|
||||
template<class T>
|
||||
operator T*() const {
|
||||
return 0;
|
||||
}
|
||||
template<class C, class T>
|
||||
operator T C::*() const {
|
||||
return 0;
|
||||
}
|
||||
typedef void* (etk::NullPtr::*bool_)() const;
|
||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) {
|
||||
throw;
|
||||
}
|
||||
};
|
||||
inline NullPtr getNullPointer() {
|
||||
// etk::nullptr exists.
|
||||
NullPtr n = { };
|
||||
return n;
|
||||
}
|
||||
}
|
||||
// If somebody hasn't already defined nullptr in a custom way...
|
||||
#if !defined(nullptr)
|
||||
#define nullptr etk::getNullPointer()
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(T* p, const etk::NullPtr) {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(const etk::NullPtr, T* p) {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
inline bool operator==(T U::* p, const etk::NullPtr) {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
inline bool operator==(const etk::NullPtr, T U::* p) {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const etk::NullPtr, const etk::NullPtr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator!=(const etk::NullPtr, const etk::NullPtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator<(const etk::NullPtr, const etk::NullPtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator>(const etk::NullPtr, const etk::NullPtr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator<=(const etk::NullPtr, const etk::NullPtr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool operator>=(const etk::NullPtr, const etk::NullPtr) {
|
||||
return true;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <etk/String.hpp>
|
||||
#include <etk/UString.hpp>
|
||||
#include <etk/Pair.hpp>
|
||||
#include <memory>
|
||||
|
||||
#define TK_REG_DEBUG TK_HIDDEN
|
||||
//#define TK_REG_DEBUG TK_VERBOSE
|
||||
|
@ -316,11 +316,11 @@ const etk::String::Iterator etk::String::begin() const {
|
||||
}
|
||||
|
||||
etk::String::Iterator etk::String::end() {
|
||||
return position( size()-1 );
|
||||
return position( size() );
|
||||
}
|
||||
|
||||
const etk::String::Iterator etk::String::end() const {
|
||||
return position( size()-1 );
|
||||
return position( size() );
|
||||
}
|
||||
|
||||
void etk::String::resize(size_t _newSize, char _value) {
|
||||
|
@ -194,6 +194,9 @@ namespace etk {
|
||||
m_string(const_cast<String*>(_obj)) {
|
||||
// nothing to do ...
|
||||
}
|
||||
size_t getCurrent() const {
|
||||
return m_current;
|
||||
}
|
||||
friend class String;
|
||||
};
|
||||
private:
|
||||
@ -359,30 +362,50 @@ namespace etk {
|
||||
* @param[in] _nbElement Number of element to add in the String
|
||||
*/
|
||||
void insert(size_t _pos, const char* _item, size_t _nbElement);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const char* _item, size_t _nbElement) {
|
||||
insert(_pos.getCurrent(), _item, _nbElement);
|
||||
};
|
||||
/**
|
||||
* @brief Insert one element in the String at a specific position
|
||||
* @param[in] _pos Position to add the elements.
|
||||
* @param[in] _item Element to add.
|
||||
*/
|
||||
void insert(size_t _pos, const char _item);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const char _item) {
|
||||
insert(_pos.getCurrent(), _item);
|
||||
}
|
||||
/**
|
||||
* @brief Insert one element in the String at a specific position
|
||||
* @param[in] _pos Position to add the elements.
|
||||
* @param[in] _item Element to add.
|
||||
*/
|
||||
void insert(size_t _pos, const String& _value);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const String& _value) {
|
||||
insert(_pos.getCurrent(), _value);
|
||||
}
|
||||
/**
|
||||
* @brief Remove N element
|
||||
* @param[in] _pos Position to remove the data
|
||||
* @param[in] _nbElement number of element to remove
|
||||
*/
|
||||
void erase(size_t _pos, size_t _nbElement=1);
|
||||
//! @previous
|
||||
void erase(const Iterator& _pos) {
|
||||
erase(_pos.getCurrent(), 1);
|
||||
}
|
||||
/**
|
||||
* @brief Remove N elements
|
||||
* @param[in] _pos Position to remove the data
|
||||
* @param[in] _posEnd Last position number
|
||||
* @param[in] _start Position to remove the data
|
||||
* @param[in] _stop Last position number
|
||||
*/
|
||||
void eraseRange(size_t _pos, size_t _posEnd);
|
||||
void eraseRange(size_t _start, size_t _stop);
|
||||
//! @previous
|
||||
void erase(const Iterator& _start, const Iterator& _stop) {
|
||||
eraseRange(_start.getCurrent(), _stop.getCurrent());
|
||||
}
|
||||
/**
|
||||
* @brief extract data between two point :
|
||||
* @param[in] _posStart start position to extract data
|
||||
@ -390,6 +413,10 @@ namespace etk {
|
||||
* @return the extracted string
|
||||
*/
|
||||
etk::String extract(size_t _posStart = 0, size_t _posEnd=etk::String::npos) const;
|
||||
//! @previous
|
||||
etk::String extract(const Iterator& _start, const Iterator& _stop) const {
|
||||
return extract(_start.getCurrent(), _stop.getCurrent());
|
||||
}
|
||||
/**
|
||||
* @brief Get the pointer on the data
|
||||
* @return pointer on the "C" string
|
||||
@ -401,18 +428,21 @@ namespace etk {
|
||||
* @return The Iterator
|
||||
*/
|
||||
Iterator position(size_t _pos);
|
||||
//! @previous
|
||||
const Iterator position(size_t _pos) const;
|
||||
/**
|
||||
* @brief Get an Iterator on the start position of the String
|
||||
* @return The Iterator
|
||||
*/
|
||||
Iterator begin();
|
||||
//! @previous
|
||||
const Iterator begin() const;
|
||||
/**
|
||||
* @brief Get an Iterator on the end position of the String
|
||||
* @return The Iterator
|
||||
*/
|
||||
Iterator end();
|
||||
//! @previous
|
||||
const Iterator end() const;
|
||||
/**
|
||||
* @brief Change the current size of the string
|
||||
@ -465,6 +495,25 @@ namespace etk {
|
||||
String operator+ (const char* _left, const String& _right);
|
||||
String operator+ (const String& _left, char _right);
|
||||
String operator+ (char _left, const String& _right);
|
||||
|
||||
inline bool operator== (const char* _left, const String& _right) {
|
||||
return _right == _left;
|
||||
}
|
||||
inline bool operator!= (const char* _left, const String& _right) {
|
||||
return _right != _left;
|
||||
}
|
||||
inline bool operator> (const char* _left, const String& _right) {
|
||||
return _right > _left;
|
||||
}
|
||||
inline bool operator>= (const char* _left, const String& _right) {
|
||||
return _right >= _left;
|
||||
}
|
||||
inline bool operator< (const char* _left, const String& _right) {
|
||||
return _right < _left;
|
||||
}
|
||||
inline bool operator<= (const char* _left, const String& _right) {
|
||||
return _right <= _left;
|
||||
}
|
||||
/**
|
||||
* @brief Template to declare conversion from anything in etk::String
|
||||
* @param[in] _variable Variable to convert
|
||||
|
@ -195,6 +195,9 @@ namespace etk {
|
||||
m_string(const_cast<UString*>(_obj)) {
|
||||
// nothing to do ...
|
||||
}
|
||||
size_t getCurrent() const {
|
||||
return m_current;
|
||||
}
|
||||
friend class UString;
|
||||
};
|
||||
private:
|
||||
@ -358,30 +361,50 @@ namespace etk {
|
||||
* @param[in] _nbElement Number of element to add in the String
|
||||
*/
|
||||
void insert(size_t _pos, const char32_t* _item, size_t _nbElement);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const char32_t* _item, size_t _nbElement) {
|
||||
insert(_pos.getCurrent(), _item, _nbElement);
|
||||
};
|
||||
/**
|
||||
* @brief Insert one element in the String at a specific position
|
||||
* @param[in] _pos Position to add the elements.
|
||||
* @param[in] _item Element to add.
|
||||
*/
|
||||
void insert(size_t _pos, const char32_t _item);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const char32_t _item) {
|
||||
insert(_pos.getCurrent(), _item);
|
||||
}
|
||||
/**
|
||||
* @brief Insert one element in the String at a specific position
|
||||
* @param[in] _pos Position to add the elements.
|
||||
* @param[in] _item Element to add.
|
||||
*/
|
||||
void insert(size_t _pos, const etk::UString& _value);
|
||||
//! @previous
|
||||
void insert(const Iterator& _pos, const UString& _value) {
|
||||
insert(_pos.getCurrent(), _value);
|
||||
}
|
||||
/**
|
||||
* @brief Remove N element
|
||||
* @param[in] _pos Position to remove the data
|
||||
* @param[in] _nbElement number of element to remove
|
||||
*/
|
||||
void erase(size_t _pos, size_t _nbElement=1);
|
||||
//! @previous
|
||||
void erase(const Iterator& _pos) {
|
||||
erase(_pos.getCurrent(), 1);
|
||||
}
|
||||
/**
|
||||
* @brief Remove N elements
|
||||
* @param[in] _pos Position to remove the data
|
||||
* @param[in] _posEnd Last position number
|
||||
* @param[in] _start Position to remove the data
|
||||
* @param[in] _stop Last position number
|
||||
*/
|
||||
void eraseRange(size_t _pos, size_t _posEnd);
|
||||
void eraseRange(size_t _start, size_t _stop);
|
||||
//! @previous
|
||||
void erase(const Iterator& _start, const Iterator& _stop) {
|
||||
eraseRange(_start.getCurrent(), _stop.getCurrent());
|
||||
}
|
||||
/**
|
||||
* @brief extract data between two point :
|
||||
* @param[in] _posStart start position to extract data
|
||||
@ -389,6 +412,10 @@ namespace etk {
|
||||
* @return the extracted string
|
||||
*/
|
||||
etk::UString extract(size_t _posStart = 0, size_t _posEnd=etk::UString::npos) const;
|
||||
//! @previous
|
||||
etk::UString extract(const Iterator& _start, const Iterator& _stop) const {
|
||||
return extract(_start.getCurrent(), _stop.getCurrent());
|
||||
}
|
||||
/**
|
||||
* @brief Get the pointer on the data
|
||||
* @return pointer on the "C" string
|
||||
|
@ -10,9 +10,10 @@
|
||||
#include <etk/debug.hpp>
|
||||
#include <elog/elog.hpp>
|
||||
#include <etk/os/FSNode.hpp>
|
||||
#include <etk/Function.hpp>
|
||||
|
||||
static int32_t nbTimeInit = 0;
|
||||
|
||||
uint32_t etk::MM___pppppp = 0;
|
||||
void etk::unInit() {
|
||||
if (nbTimeInit > 1) {
|
||||
nbTimeInit--;
|
||||
|
@ -1,2 +1,35 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||
* @license MPL v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace etk {
|
||||
template <class TYPE> const TYPE& min(const TYPE& _val1, const TYPE& _val2) {
|
||||
return (_val1 > _val2) ? _val2 : _val1;
|
||||
}
|
||||
template <class TYPE> const TYPE& max(const TYPE& _val1, const TYPE& _val2) {
|
||||
return (_val1 > _val2) ? _val1 : _val2;
|
||||
}
|
||||
/**
|
||||
* @brief in std, we have min, max but not avg ==> it is missing... the Define of avg template.
|
||||
* @param[in] _min Minimum value of the range
|
||||
* @param[in] _val The value that we want a min/max
|
||||
* @param[in] _max Maximum value of the range
|
||||
* @return Value that min/max applied
|
||||
*/
|
||||
template <class TYPE> const TYPE& avg(const TYPE& _min, const TYPE& _val, const TYPE& _max) {
|
||||
return etk::min(etk::max(_min,_val),_max);
|
||||
}
|
||||
template<class ETK_ITERATOR_TYPE>
|
||||
size_t distance(const ETK_ITERATOR_TYPE& _start, const ETK_ITERATOR_TYPE& _stop) {
|
||||
size_t out = 0;
|
||||
ETK_ITERATOR_TYPE tmp = _start;
|
||||
while (tmp != _stop) {
|
||||
out++;
|
||||
++tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
@ -109,4 +109,49 @@ namespace etk {
|
||||
public etk::IntegralConstant<bool, __is_base_of(ETK_TYPE, ETK_TYPE_DERIVED)> {
|
||||
|
||||
};
|
||||
|
||||
template<typename>
|
||||
struct IsFunction;
|
||||
|
||||
template<typename>
|
||||
struct IsFunction :
|
||||
public etk::typeFalse {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...)>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...)&>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...)&&>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...) const>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...) const &>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
|
||||
template<typename ETK_TYPE_RETURN, typename... ETK_TYPE_ARGS>
|
||||
struct IsFunction<ETK_TYPE_RETURN(ETK_TYPE_ARGS...) const &&>:
|
||||
public etk::typeTrue {
|
||||
|
||||
};
|
||||
}
|
||||
|
117
etk/types.hpp
117
etk/types.hpp
@ -88,121 +88,8 @@ extern "C" {
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
typedef decltype(nullptr) etk::NullPtr;
|
||||
#else
|
||||
namespace etk {
|
||||
class NullPtr {
|
||||
public:
|
||||
// When tested a pointer, acts as 0.
|
||||
template<class T>
|
||||
operator T*() const {
|
||||
return 0;
|
||||
}
|
||||
template<class C, class T> // When tested as a member pointer, acts as 0.
|
||||
operator T C::*() const {
|
||||
return 0;
|
||||
}
|
||||
typedef void* (etk::NullPtr::*bool_)() const;
|
||||
// An rvalue of type etk::NullPtr can be converted to an rvalue of type bool; the resulting value is false.
|
||||
/*
|
||||
operator bool_() const {
|
||||
// We can't use operator bool(){ return false; } because bool is convertable to int which breaks other required functionality.
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
// We can't enable this without generating warnings about nullptr being uninitialized after being used when created without "= {}".
|
||||
//void* mSizeofVoidPtr; // sizeof(etk::NullPtr) == sizeof(void*). Needs to be public if etk::NullPtr is to be a POD.
|
||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) {
|
||||
throw;
|
||||
//return ETK_TYPE_FUNCTION_RETURN();
|
||||
}
|
||||
private:
|
||||
//void operator&() const; // Address cannot be taken. ==> TODO: this is really bad, because this create an error in many code
|
||||
};
|
||||
#include <etk/NullPtr.hpp>
|
||||
|
||||
inline NullPtr nullptrGet() {
|
||||
// etk::nullptr exists.
|
||||
NullPtr n = { };
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
// If somebody hasn't already defined nullptr in a custom way...
|
||||
#if !defined(nullptr)
|
||||
#define nullptr etk::nullptrGet()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(T* p, const etk::NullPtr) {
|
||||
return p == 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(const etk::NullPtr, T* p)
|
||||
{ return p == 0; }
|
||||
|
||||
template<class T, class U>
|
||||
inline bool operator==(T U::* p, const etk::NullPtr)
|
||||
{ return p == 0; }
|
||||
|
||||
template<class T, class U>
|
||||
inline bool operator==(const etk::NullPtr, T U::* p)
|
||||
{ return p == 0; }
|
||||
|
||||
inline bool operator==(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return true; }
|
||||
|
||||
inline bool operator!=(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return false; }
|
||||
|
||||
inline bool operator<(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return false; }
|
||||
|
||||
inline bool operator>(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return false; }
|
||||
|
||||
inline bool operator<=(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return true; }
|
||||
|
||||
inline bool operator>=(const etk::NullPtr, const etk::NullPtr)
|
||||
{ return true; }
|
||||
|
||||
// TODO: remove ...
|
||||
// exported to global namespace.
|
||||
//using etk::NullPtr;
|
||||
|
||||
|
||||
namespace etk {
|
||||
template <class TYPE> const TYPE& min(const TYPE& _val1, const TYPE& _val2) {
|
||||
return (_val1 > _val2) ? _val2 : _val1;
|
||||
}
|
||||
template <class TYPE> const TYPE& max(const TYPE& _val1, const TYPE& _val2) {
|
||||
return (_val1 > _val2) ? _val1 : _val2;
|
||||
}
|
||||
/**
|
||||
* @brief in std, we have min, max but not avg ==> it is missing... the Define of avg template.
|
||||
* @param[in] _min Minimum value of the range
|
||||
* @param[in] _val The value that we want a min/max
|
||||
* @param[in] _max Maximum value of the range
|
||||
* @return Value that min/max applied
|
||||
*/
|
||||
template <class TYPE> const TYPE& avg(const TYPE& _min, const TYPE& _val, const TYPE& _max) {
|
||||
return etk::min(etk::max(_min,_val),_max);
|
||||
}
|
||||
template<class ETK_ITERATOR_TYPE>
|
||||
size_t distance(const ETK_ITERATOR_TYPE& _start, const ETK_ITERATOR_TYPE& _stop) {
|
||||
size_t out = 0;
|
||||
ETK_ITERATOR_TYPE tmp = _start;
|
||||
while (tmp != _stop) {
|
||||
out++;
|
||||
++tmp;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
#include <etk/stdTools.hpp>
|
||||
#include <etk/move.hpp>
|
||||
#include <etk/Stream.hpp>
|
||||
|
@ -51,6 +51,7 @@ def configure(target, my_module):
|
||||
'etk/move.hpp',
|
||||
'etk/typeTrait.hpp',
|
||||
'etk/Function.hpp',
|
||||
'etk/NullPtr.hpp',
|
||||
])
|
||||
|
||||
# build in C++ mode
|
||||
|
@ -42,6 +42,7 @@ def configure(target, my_module):
|
||||
'test/testQuaternion.cpp',
|
||||
'test/testVector2_f.cpp',
|
||||
'test/testString.cpp',
|
||||
'test/testTrait.cpp',
|
||||
])
|
||||
my_module.add_depend([
|
||||
'etk',
|
||||
|
@ -51,6 +51,7 @@ TEST(TestFunction, setALambda) {
|
||||
etk::Function<void()> f_display = []() { print_num(642); };;
|
||||
EXPECT_NE(f_display, nullptr);
|
||||
}
|
||||
|
||||
TEST(TestFunction, callAlLambda) {
|
||||
globalValue = 0;
|
||||
// Test contructor value
|
||||
@ -59,6 +60,58 @@ TEST(TestFunction, callAlLambda) {
|
||||
EXPECT_EQ(globalValue, 42 + 1000);
|
||||
}
|
||||
|
||||
class testObject {
|
||||
private:
|
||||
uint32_t m_id;
|
||||
public:
|
||||
testObject(int32_t iii) {
|
||||
m_id = iii;
|
||||
TEST_DEBUG("Call testObject Contructor " << m_id);
|
||||
}
|
||||
~testObject() {
|
||||
TEST_DEBUG("Call testObject Destructor " << m_id);
|
||||
}
|
||||
void operator() (int32_t iii) {
|
||||
globalValue = m_id + iii;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
TEST(TestFunction, setCallableObject) {
|
||||
globalValue = 0;
|
||||
// Test contructor value
|
||||
testObject tmp(100000);
|
||||
etk::Function<void(int32_t)> f_display = tmp;
|
||||
EXPECT_NE(f_display, nullptr);
|
||||
}
|
||||
|
||||
TEST(TestFunction, callCallableObject) {
|
||||
globalValue = 0;
|
||||
// Test contructor value
|
||||
testObject tmp(550000);
|
||||
etk::Function<void(int32_t)> f_display = tmp;
|
||||
f_display(43);
|
||||
EXPECT_EQ(globalValue, 43 + 550000);
|
||||
}
|
||||
*/
|
||||
etk::Function<void(int32_t)> createTmpFunction(uint32_t _value) {
|
||||
return [=](int32_t _data) { globalValue = _value + _data;};
|
||||
}
|
||||
|
||||
TEST(TestFunction, setLambdaOnStack) {
|
||||
globalValue = 0;
|
||||
etk::Function<void(int32_t)> f_display = createTmpFunction(87000);
|
||||
EXPECT_NE(f_display, nullptr);
|
||||
}
|
||||
|
||||
TEST(TestFunction, callLambdaOnStack) {
|
||||
globalValue = 0;
|
||||
etk::Function<void(int32_t)> f_display = createTmpFunction(88000);
|
||||
f_display(44);
|
||||
EXPECT_EQ(globalValue, 44 + 88000);
|
||||
}
|
||||
|
||||
/*
|
||||
TEST(TestFunction, setAMemberFunction) {
|
||||
globalValue = 0;
|
||||
// Test contructor value
|
||||
@ -74,4 +127,5 @@ TEST(TestFunction, callAMemberFunction) {
|
||||
f_display(foo, 16);
|
||||
EXPECT_EQ(globalValue, 16 + 70000);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -11,30 +11,37 @@
|
||||
|
||||
TEST(typeTrait, RemoveConstVolatile_1) {
|
||||
typedef std::remove_cv<const int>::type type1;
|
||||
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
|
||||
auto ret = etk::IsSame<int, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, RemoveConstVolatile_2) {
|
||||
typedef std::remove_cv<volatile int>::type type1;
|
||||
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
|
||||
auto ret = etk::IsSame<int, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, RemoveConstVolatile_3) {
|
||||
typedef std::remove_cv<const volatile int>::type type1;
|
||||
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
|
||||
auto ret = etk::IsSame<int, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, RemoveConstVolatile_4) {
|
||||
typedef std::remove_cv<const volatile int*>::type type1;
|
||||
EXPECT_EQ(etk::IsSame<const volatile int*, type1>::value, true);
|
||||
auto ret = etk::IsSame<const volatile int*, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, RemoveConstVolatile_5) {
|
||||
typedef std::remove_cv<int* const volatile>::type type1;
|
||||
EXPECT_EQ(etk::IsSame<int*, type1>::value, true);
|
||||
auto ret = etk::IsSame<int*, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
|
||||
TEST(typeTrait, IsVoid_1) {
|
||||
EXPECT_EQ(etk::IsVoid<void>::value, true);
|
||||
auto ret = etk::IsVoid<void>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsVoid_2) {
|
||||
EXPECT_EQ(etk::IsVoid<int>::value, false);
|
||||
auto ret = etk::IsVoid<int>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
class A {};
|
||||
@ -44,52 +51,79 @@ class B : A {};
|
||||
class C {};
|
||||
|
||||
TEST(typeTrait, IsBaseOf_1) {
|
||||
EXPECT_EQ(etk::IsBaseOf<A, B>::value, true);
|
||||
auto ret = etk::IsBaseOf<A, B>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
|
||||
TEST(typeTrait, IsBaseOf_2) {
|
||||
EXPECT_EQ(etk::IsBaseOf<B, A>::value, false);
|
||||
auto ret = etk::IsBaseOf<B, A>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
TEST(typeTrait, IsBaseOf_3) {
|
||||
EXPECT_EQ(etk::IsBaseOf<C, B>::value, false);
|
||||
auto ret = etk::IsBaseOf<C, B>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
TEST(typeTrait, IsBaseOf_4) {
|
||||
EXPECT_EQ(etk::IsBaseOf<C, C>::value, true);
|
||||
auto ret = etk::IsBaseOf<C, C>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST(typeTrait, isSame_nullptr) {
|
||||
typedef etk::NullPtr type1;
|
||||
auto ret = etk::IsSame<etk::NullPtr, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
/*
|
||||
TEST(typeTrait, isSame_nullptr2) {
|
||||
typedef etk::NullPtr type1;
|
||||
auto ret = etk::IsSame<nullptr, type1>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
*/
|
||||
|
||||
TEST(typeTrait, IsSame_1) {
|
||||
EXPECT_EQ(etk::IsSame<int, int32_t>::value, true);
|
||||
auto ret = etk::IsSame<int, int32_t>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsSame_2) {
|
||||
EXPECT_EQ(etk::IsSame<int, int64_t>::value, false);
|
||||
auto ret = etk::IsSame<int, int64_t>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsSame_3) {
|
||||
EXPECT_EQ(etk::IsSame<float, int32_t>::value, false);
|
||||
auto ret = etk::IsSame<float, int32_t>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
|
||||
TEST(typeTrait, IsSame_4) {
|
||||
EXPECT_EQ(etk::IsSame<int, int>::value, true);
|
||||
auto ret = etk::IsSame<int, int>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsSame_5) {
|
||||
EXPECT_EQ(etk::IsSame<int, unsigned int>::value, false);
|
||||
auto ret = etk::IsSame<int, unsigned int>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsSame_6) {
|
||||
EXPECT_EQ(etk::IsSame<int, signed int>::value, true);
|
||||
auto ret = etk::IsSame<int, signed int>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
|
||||
|
||||
TEST(typeTrait, IsSame_7) {
|
||||
EXPECT_EQ(etk::IsSame<char, char>::value, true);
|
||||
auto ret = etk::IsSame<char, char>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsSame_8) {
|
||||
EXPECT_EQ(etk::IsSame<char, unsigned char>::value, false);
|
||||
auto ret = etk::IsSame<char, unsigned char>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsSame_9) {
|
||||
EXPECT_EQ(etk::IsSame<char, signed char>::value, false);
|
||||
auto ret = etk::IsSame<char, signed char>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
|
||||
@ -101,16 +135,20 @@ class K_B {};
|
||||
enum class K_C {};
|
||||
|
||||
TEST(typeTrait, IsClass_1) {
|
||||
EXPECT_EQ(etk::IsClass<K_A>::value, true);
|
||||
auto ret = etk::IsClass<K_A>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsClass_2) {
|
||||
EXPECT_EQ(etk::IsClass<K_B>::value, true);
|
||||
auto ret = etk::IsClass<K_B>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsClass_3) {
|
||||
EXPECT_EQ(etk::IsClass<K_C>::value, false);
|
||||
auto ret = etk::IsClass<K_C>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsClass_4) {
|
||||
EXPECT_EQ(etk::IsClass<int>::value, false);
|
||||
auto ret = etk::IsClass<int>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
|
||||
@ -129,16 +167,20 @@ struct J_C {
|
||||
};
|
||||
|
||||
TEST(typeTrait, IsUnion_1) {
|
||||
EXPECT_EQ(etk::IsUnion<K_A>::value, false);
|
||||
auto ret = etk::IsUnion<K_A>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsUnion_2) {
|
||||
EXPECT_EQ(etk::IsUnion<K_B>::value, true);
|
||||
auto ret = etk::IsUnion<K_B>::value;
|
||||
EXPECT_EQ(ret, true);
|
||||
}
|
||||
TEST(typeTrait, IsUnion_3) {
|
||||
EXPECT_EQ(etk::IsUnion<K_C>::value, false);
|
||||
auto ret = etk::IsUnion<K_C>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
TEST(typeTrait, IsUnion_4) {
|
||||
EXPECT_EQ(etk::IsUnion<int>::value, false);
|
||||
auto ret = etk::IsUnion<int>::value;
|
||||
EXPECT_EQ(ret, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,8 +32,6 @@ TEST(TestVector2D_f, constructor) {
|
||||
TEST(TestVector2D_f, constructorString) {
|
||||
etk::Vector2D<float> vect1("(4,-8.5)");
|
||||
EXPECT_EQ(vect1, etk::Vector2D<float>(4.0,-8.5));
|
||||
EXPECT_FLOAT_EQ(vect1.y(), -8.5);
|
||||
EXPECT_FLOAT_EQ(vect1.y(), -8.5);
|
||||
etk::Vector2D<float> vect2("-6,5.5");
|
||||
EXPECT_FLOAT_EQ(vect2.x(), -6.0);
|
||||
EXPECT_FLOAT_EQ(vect2.y(), 5.5);
|
||||
|
Loading…
x
Reference in New Issue
Block a user