[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") {
|
} else if (data == "--etest-list") {
|
||||||
listAllTest();
|
listAllTest();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
} else if (data == "--etest-filter=") {
|
||||||
|
ETEST_PRINT("Missing data in the filter list...");
|
||||||
|
exit(0);
|
||||||
} else if (data.startWith("--etest-filter=") == true) {
|
} else if (data.startWith("--etest-filter=") == true) {
|
||||||
etk::String filter = &data[15];
|
etk::String filter = &data[15];
|
||||||
ETEST_PRINT(" Filter: " << filter);
|
ETEST_PRINT(" Filter: " << filter);
|
||||||
@ -199,7 +202,7 @@ int32_t etest::runAllTest() {
|
|||||||
}
|
}
|
||||||
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":");
|
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":");
|
||||||
echrono::Steady ticGroup = echrono::Steady::now();
|
echrono::Steady ticGroup = echrono::Steady::now();
|
||||||
for (auto &it: getListOfTest()) {
|
for (auto &it: runList) {
|
||||||
if (it->getTestGroup() != itGroup) {
|
if (it->getTestGroup() != itGroup) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ namespace etest {
|
|||||||
|
|
||||||
#define EXPECT_EQ(element, result) \
|
#define EXPECT_EQ(element, result) \
|
||||||
do { \
|
do { \
|
||||||
bool ETEST_VARIABLE_TMP_res = (element == result); \
|
bool ETEST_VARIABLE_TMP_res = ((element) == (result)); \
|
||||||
if (etest::g_currentTest == nullptr) { \
|
if (etest::g_currentTest == nullptr) { \
|
||||||
ETEST_CRITICAL("Not in a test"); \
|
ETEST_CRITICAL("Not in a test"); \
|
||||||
} else { \
|
} else { \
|
||||||
@ -166,7 +166,7 @@ namespace etest {
|
|||||||
|
|
||||||
#define EXPECT_NE(element, result) \
|
#define EXPECT_NE(element, result) \
|
||||||
do { \
|
do { \
|
||||||
bool ETEST_VARIABLE_TMP_res = (element != result); \
|
bool ETEST_VARIABLE_TMP_res = ((element) != (result)); \
|
||||||
if (etest::g_currentTest == nullptr) { \
|
if (etest::g_currentTest == nullptr) { \
|
||||||
ETEST_CRITICAL("Not in a test"); \
|
ETEST_CRITICAL("Not in a test"); \
|
||||||
} else { \
|
} else { \
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
#include <etk/debug.hpp>
|
#include <etk/debug.hpp>
|
||||||
#include <etk/stdTools.hpp>
|
#include <etk/stdTools.hpp>
|
||||||
#include <etk/String.hpp>
|
#include <etk/String.hpp>
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
class ColorList {
|
class ColorList {
|
||||||
public:
|
public:
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include <etk/String.hpp>
|
#include <etk/String.hpp>
|
||||||
#include <etk/UString.hpp>
|
#include <etk/UString.hpp>
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
/**
|
/**
|
||||||
|
341
etk/Function.hpp
341
etk/Function.hpp
@ -1,18 +1,22 @@
|
|||||||
/** @file
|
/** @file
|
||||||
* @author Edouard DUPIN
|
* @author Edouard DUPIN
|
||||||
* @copyright 2011, Edouard DUPIN, all right reserved
|
* @copyright 2017, Edouard DUPIN, all right reserved
|
||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <etk/types.hpp>
|
#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 {
|
namespace etk {
|
||||||
|
template <typename ETK_TYPE_FUNCTOR, typename ETK_TYPE_FUNCTION>
|
||||||
|
class FunctionPrivateLambda;
|
||||||
template <typename ETK_TYPE_FUNCTION>
|
template <typename ETK_TYPE_FUNCTION>
|
||||||
class FunctionPrivateSpecific;
|
class FunctionPrivateFunction;
|
||||||
template <typename ETK_TYPE_FUNCTION>
|
template <typename ETK_TYPE_FUNCTION>
|
||||||
class FunctionPrivate;
|
class FunctionPrivate;
|
||||||
|
|
||||||
@ -22,241 +26,170 @@ namespace etk {
|
|||||||
virtual ~FunctionPrivate() {
|
virtual ~FunctionPrivate() {
|
||||||
|
|
||||||
}
|
}
|
||||||
// other constructors, from nullptr, from function pointers
|
|
||||||
virtual ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const = 0;
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
template <typename ETK_TYPE_FUNCTION_FUNCTOR, typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
|
||||||
class FunctionPrivateSpecific<ETK_TYPE_FUNCTION_RETURN(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...)> {
|
public FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
|
||||||
private:
|
private:
|
||||||
// function pointer types for the type-erasure behaviors
|
ETK_TYPE_FUNCTION_FUNCTOR m_dataPointer;
|
||||||
// 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;
|
|
||||||
public:
|
public:
|
||||||
FunctionPrivateSpecific():
|
FunctionPrivateLambda(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
||||||
invoke_f(nullptr),
|
m_dataPointer(_functor) {
|
||||||
#ifdef ETK_FUNCTION_ENABLE_NEW
|
ETK_FUNCTION_DEBUG(" NEW FunctionPrivateLambda \n");
|
||||||
construct_f(nullptr),
|
|
||||||
#endif
|
|
||||||
destroy_f(nullptr),
|
|
||||||
m_dataPointer(nullptr) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
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):
|
FunctionPrivateLambda(const ETK_TYPE_FUNCTION_FUNCTOR& _functor):
|
||||||
invoke_f(_obj.invoke_f),
|
m_dataPointer(_functor) {
|
||||||
construct_f(_obj.construct_f),
|
ETK_FUNCTION_DEBUG(" NEW FunctionPrivateLambda \n");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#else
|
~FunctionPrivateLambda() {
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#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 {
|
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) const {
|
||||||
return invoke_f(m_dataPointer,
|
return m_dataPointer(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
||||||
etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
|
||||||
}
|
}
|
||||||
|
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* copy() {
|
||||||
bool operator!= (etk::NullPtr) const {
|
ETK_FUNCTION_DEBUG(" COPY FunctionPrivateLambda \n");
|
||||||
return m_dataPointer != nullptr;
|
return new FunctionPrivateLambda(m_dataPointer);
|
||||||
}
|
|
||||||
bool operator== (etk::NullPtr) const {
|
|
||||||
return m_dataPointer == nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ETK_TYPE_FUNCTION>
|
template <typename ETK_TYPE_FUNCTION>
|
||||||
class Function;
|
class Function;
|
||||||
|
|
||||||
|
extern uint32_t MM___pppppp;
|
||||||
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...)> {
|
||||||
private:
|
private:
|
||||||
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* m_pointerPrivate;
|
FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* m_pointerPrivate;
|
||||||
|
uint32_t m_pppppp;
|
||||||
public:
|
public:
|
||||||
Function():
|
Function():
|
||||||
m_pointerPrivate(nullptr) {
|
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_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
|
Function(const Function& _obj):
|
||||||
// construct from any functor type
|
m_pointerPrivate(nullptr) {
|
||||||
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
|
m_pppppp = MM___pppppp++;
|
||||||
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
|
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);
|
||||||
m_pointerPrivate(new FunctionPrivateSpecific<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>(_functor)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
// copy constructor
|
|
||||||
Function(const Function& _obj):
|
|
||||||
m_pointerPrivate(nullptr) {
|
|
||||||
if (_obj.m_pointerPrivate != nullptr) {
|
|
||||||
m_pointerPrivate = _obj.m_pointerPrivate->copy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
~Function() {
|
|
||||||
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) {
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return (*m_pointerPrivate)(etk::forward<ETK_TYPE_FUNCTION_ARGS>(_args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!= (etk::NullPtr) const {
|
|
||||||
return m_pointerPrivate != nullptr;
|
|
||||||
}
|
|
||||||
bool operator== (etk::NullPtr) const {
|
|
||||||
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) {
|
if (_obj.m_pointerPrivate != nullptr) {
|
||||||
m_pointerPrivate = _obj.m_pointerPrivate->copy();
|
m_pointerPrivate = _obj.m_pointerPrivate->copy();
|
||||||
}
|
}
|
||||||
return *this;
|
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);
|
||||||
}
|
}
|
||||||
#endif
|
Function(Function&& _obj):
|
||||||
Function& operator= (Function&& _obj) {
|
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;
|
delete m_pointerPrivate;
|
||||||
m_pointerPrivate = _obj.m_pointerPrivate;
|
m_pointerPrivate = nullptr;
|
||||||
_obj.m_pointerPrivate = nullptr;
|
}
|
||||||
|
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;
|
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;
|
||||||
|
}
|
||||||
|
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/String.hpp>
|
||||||
#include <etk/UString.hpp>
|
#include <etk/UString.hpp>
|
||||||
#include <etk/Pair.hpp>
|
#include <etk/Pair.hpp>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#define TK_REG_DEBUG TK_HIDDEN
|
#define TK_REG_DEBUG TK_HIDDEN
|
||||||
//#define TK_REG_DEBUG TK_VERBOSE
|
//#define TK_REG_DEBUG TK_VERBOSE
|
||||||
|
@ -316,11 +316,11 @@ const etk::String::Iterator etk::String::begin() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
etk::String::Iterator etk::String::end() {
|
etk::String::Iterator etk::String::end() {
|
||||||
return position( size()-1 );
|
return position( size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
const etk::String::Iterator etk::String::end() const {
|
const etk::String::Iterator etk::String::end() const {
|
||||||
return position( size()-1 );
|
return position( size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::String::resize(size_t _newSize, char _value) {
|
void etk::String::resize(size_t _newSize, char _value) {
|
||||||
|
@ -194,6 +194,9 @@ namespace etk {
|
|||||||
m_string(const_cast<String*>(_obj)) {
|
m_string(const_cast<String*>(_obj)) {
|
||||||
// nothing to do ...
|
// nothing to do ...
|
||||||
}
|
}
|
||||||
|
size_t getCurrent() const {
|
||||||
|
return m_current;
|
||||||
|
}
|
||||||
friend class String;
|
friend class String;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
@ -359,30 +362,50 @@ namespace etk {
|
|||||||
* @param[in] _nbElement Number of element to add in the String
|
* @param[in] _nbElement Number of element to add in the String
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const char* _item, size_t _nbElement);
|
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
|
* @brief Insert one element in the String at a specific position
|
||||||
* @param[in] _pos Position to add the elements.
|
* @param[in] _pos Position to add the elements.
|
||||||
* @param[in] _item Element to add.
|
* @param[in] _item Element to add.
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const char _item);
|
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
|
* @brief Insert one element in the String at a specific position
|
||||||
* @param[in] _pos Position to add the elements.
|
* @param[in] _pos Position to add the elements.
|
||||||
* @param[in] _item Element to add.
|
* @param[in] _item Element to add.
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const String& _value);
|
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
|
* @brief Remove N element
|
||||||
* @param[in] _pos Position to remove the data
|
* @param[in] _pos Position to remove the data
|
||||||
* @param[in] _nbElement number of element to remove
|
* @param[in] _nbElement number of element to remove
|
||||||
*/
|
*/
|
||||||
void erase(size_t _pos, size_t _nbElement=1);
|
void erase(size_t _pos, size_t _nbElement=1);
|
||||||
|
//! @previous
|
||||||
|
void erase(const Iterator& _pos) {
|
||||||
|
erase(_pos.getCurrent(), 1);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Remove N elements
|
* @brief Remove N elements
|
||||||
* @param[in] _pos Position to remove the data
|
* @param[in] _start Position to remove the data
|
||||||
* @param[in] _posEnd Last position number
|
* @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 :
|
* @brief extract data between two point :
|
||||||
* @param[in] _posStart start position to extract data
|
* @param[in] _posStart start position to extract data
|
||||||
@ -390,6 +413,10 @@ namespace etk {
|
|||||||
* @return the extracted string
|
* @return the extracted string
|
||||||
*/
|
*/
|
||||||
etk::String extract(size_t _posStart = 0, size_t _posEnd=etk::String::npos) const;
|
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
|
* @brief Get the pointer on the data
|
||||||
* @return pointer on the "C" string
|
* @return pointer on the "C" string
|
||||||
@ -401,18 +428,21 @@ namespace etk {
|
|||||||
* @return The Iterator
|
* @return The Iterator
|
||||||
*/
|
*/
|
||||||
Iterator position(size_t _pos);
|
Iterator position(size_t _pos);
|
||||||
|
//! @previous
|
||||||
const Iterator position(size_t _pos) const;
|
const Iterator position(size_t _pos) const;
|
||||||
/**
|
/**
|
||||||
* @brief Get an Iterator on the start position of the String
|
* @brief Get an Iterator on the start position of the String
|
||||||
* @return The Iterator
|
* @return The Iterator
|
||||||
*/
|
*/
|
||||||
Iterator begin();
|
Iterator begin();
|
||||||
|
//! @previous
|
||||||
const Iterator begin() const;
|
const Iterator begin() const;
|
||||||
/**
|
/**
|
||||||
* @brief Get an Iterator on the end position of the String
|
* @brief Get an Iterator on the end position of the String
|
||||||
* @return The Iterator
|
* @return The Iterator
|
||||||
*/
|
*/
|
||||||
Iterator end();
|
Iterator end();
|
||||||
|
//! @previous
|
||||||
const Iterator end() const;
|
const Iterator end() const;
|
||||||
/**
|
/**
|
||||||
* @brief Change the current size of the string
|
* @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 char* _left, const String& _right);
|
||||||
String operator+ (const String& _left, char _right);
|
String operator+ (const String& _left, char _right);
|
||||||
String operator+ (char _left, const String& _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
|
* @brief Template to declare conversion from anything in etk::String
|
||||||
* @param[in] _variable Variable to convert
|
* @param[in] _variable Variable to convert
|
||||||
|
@ -195,6 +195,9 @@ namespace etk {
|
|||||||
m_string(const_cast<UString*>(_obj)) {
|
m_string(const_cast<UString*>(_obj)) {
|
||||||
// nothing to do ...
|
// nothing to do ...
|
||||||
}
|
}
|
||||||
|
size_t getCurrent() const {
|
||||||
|
return m_current;
|
||||||
|
}
|
||||||
friend class UString;
|
friend class UString;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
@ -358,30 +361,50 @@ namespace etk {
|
|||||||
* @param[in] _nbElement Number of element to add in the String
|
* @param[in] _nbElement Number of element to add in the String
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const char32_t* _item, size_t _nbElement);
|
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
|
* @brief Insert one element in the String at a specific position
|
||||||
* @param[in] _pos Position to add the elements.
|
* @param[in] _pos Position to add the elements.
|
||||||
* @param[in] _item Element to add.
|
* @param[in] _item Element to add.
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const char32_t _item);
|
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
|
* @brief Insert one element in the String at a specific position
|
||||||
* @param[in] _pos Position to add the elements.
|
* @param[in] _pos Position to add the elements.
|
||||||
* @param[in] _item Element to add.
|
* @param[in] _item Element to add.
|
||||||
*/
|
*/
|
||||||
void insert(size_t _pos, const etk::UString& _value);
|
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
|
* @brief Remove N element
|
||||||
* @param[in] _pos Position to remove the data
|
* @param[in] _pos Position to remove the data
|
||||||
* @param[in] _nbElement number of element to remove
|
* @param[in] _nbElement number of element to remove
|
||||||
*/
|
*/
|
||||||
void erase(size_t _pos, size_t _nbElement=1);
|
void erase(size_t _pos, size_t _nbElement=1);
|
||||||
|
//! @previous
|
||||||
|
void erase(const Iterator& _pos) {
|
||||||
|
erase(_pos.getCurrent(), 1);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Remove N elements
|
* @brief Remove N elements
|
||||||
* @param[in] _pos Position to remove the data
|
* @param[in] _start Position to remove the data
|
||||||
* @param[in] _posEnd Last position number
|
* @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 :
|
* @brief extract data between two point :
|
||||||
* @param[in] _posStart start position to extract data
|
* @param[in] _posStart start position to extract data
|
||||||
@ -389,6 +412,10 @@ namespace etk {
|
|||||||
* @return the extracted string
|
* @return the extracted string
|
||||||
*/
|
*/
|
||||||
etk::UString extract(size_t _posStart = 0, size_t _posEnd=etk::UString::npos) const;
|
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
|
* @brief Get the pointer on the data
|
||||||
* @return pointer on the "C" string
|
* @return pointer on the "C" string
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
#include <etk/debug.hpp>
|
#include <etk/debug.hpp>
|
||||||
#include <elog/elog.hpp>
|
#include <elog/elog.hpp>
|
||||||
#include <etk/os/FSNode.hpp>
|
#include <etk/os/FSNode.hpp>
|
||||||
|
#include <etk/Function.hpp>
|
||||||
|
|
||||||
static int32_t nbTimeInit = 0;
|
static int32_t nbTimeInit = 0;
|
||||||
|
uint32_t etk::MM___pppppp = 0;
|
||||||
void etk::unInit() {
|
void etk::unInit() {
|
||||||
if (nbTimeInit > 1) {
|
if (nbTimeInit > 1) {
|
||||||
nbTimeInit--;
|
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)> {
|
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
|
#define M_PI 3.14159265358979323846
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#include <etk/NullPtr.hpp>
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
inline NullPtr nullptrGet() {
|
|
||||||
// etk::nullptr exists.
|
|
||||||
NullPtr n = { };
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If somebody hasn't already defined nullptr in a custom way...
|
#include <etk/stdTools.hpp>
|
||||||
#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/move.hpp>
|
#include <etk/move.hpp>
|
||||||
#include <etk/Stream.hpp>
|
#include <etk/Stream.hpp>
|
||||||
|
@ -51,6 +51,7 @@ def configure(target, my_module):
|
|||||||
'etk/move.hpp',
|
'etk/move.hpp',
|
||||||
'etk/typeTrait.hpp',
|
'etk/typeTrait.hpp',
|
||||||
'etk/Function.hpp',
|
'etk/Function.hpp',
|
||||||
|
'etk/NullPtr.hpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
# build in C++ mode
|
# build in C++ mode
|
||||||
|
@ -42,6 +42,7 @@ def configure(target, my_module):
|
|||||||
'test/testQuaternion.cpp',
|
'test/testQuaternion.cpp',
|
||||||
'test/testVector2_f.cpp',
|
'test/testVector2_f.cpp',
|
||||||
'test/testString.cpp',
|
'test/testString.cpp',
|
||||||
|
'test/testTrait.cpp',
|
||||||
])
|
])
|
||||||
my_module.add_depend([
|
my_module.add_depend([
|
||||||
'etk',
|
'etk',
|
||||||
|
@ -51,6 +51,7 @@ TEST(TestFunction, setALambda) {
|
|||||||
etk::Function<void()> f_display = []() { print_num(642); };;
|
etk::Function<void()> f_display = []() { print_num(642); };;
|
||||||
EXPECT_NE(f_display, nullptr);
|
EXPECT_NE(f_display, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestFunction, callAlLambda) {
|
TEST(TestFunction, callAlLambda) {
|
||||||
globalValue = 0;
|
globalValue = 0;
|
||||||
// Test contructor value
|
// Test contructor value
|
||||||
@ -59,6 +60,58 @@ TEST(TestFunction, callAlLambda) {
|
|||||||
EXPECT_EQ(globalValue, 42 + 1000);
|
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) {
|
TEST(TestFunction, setAMemberFunction) {
|
||||||
globalValue = 0;
|
globalValue = 0;
|
||||||
// Test contructor value
|
// Test contructor value
|
||||||
@ -74,4 +127,5 @@ TEST(TestFunction, callAMemberFunction) {
|
|||||||
f_display(foo, 16);
|
f_display(foo, 16);
|
||||||
EXPECT_EQ(globalValue, 16 + 70000);
|
EXPECT_EQ(globalValue, 16 + 70000);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@ -11,30 +11,37 @@
|
|||||||
|
|
||||||
TEST(typeTrait, RemoveConstVolatile_1) {
|
TEST(typeTrait, RemoveConstVolatile_1) {
|
||||||
typedef std::remove_cv<const int>::type type1;
|
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) {
|
TEST(typeTrait, RemoveConstVolatile_2) {
|
||||||
typedef std::remove_cv<volatile int>::type type1;
|
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) {
|
TEST(typeTrait, RemoveConstVolatile_3) {
|
||||||
typedef std::remove_cv<const volatile int>::type type1;
|
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) {
|
TEST(typeTrait, RemoveConstVolatile_4) {
|
||||||
typedef std::remove_cv<const volatile int*>::type type1;
|
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) {
|
TEST(typeTrait, RemoveConstVolatile_5) {
|
||||||
typedef std::remove_cv<int* const volatile>::type type1;
|
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) {
|
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) {
|
TEST(typeTrait, IsVoid_2) {
|
||||||
EXPECT_EQ(etk::IsVoid<int>::value, false);
|
auto ret = etk::IsVoid<int>::value;
|
||||||
|
EXPECT_EQ(ret, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
class A {};
|
class A {};
|
||||||
@ -44,52 +51,79 @@ class B : A {};
|
|||||||
class C {};
|
class C {};
|
||||||
|
|
||||||
TEST(typeTrait, IsBaseOf_1) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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 {};
|
enum class K_C {};
|
||||||
|
|
||||||
TEST(typeTrait, IsClass_1) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
TEST(TestVector2D_f, constructorString) {
|
||||||
etk::Vector2D<float> vect1("(4,-8.5)");
|
etk::Vector2D<float> vect1("(4,-8.5)");
|
||||||
EXPECT_EQ(vect1, etk::Vector2D<float>(4.0,-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");
|
etk::Vector2D<float> vect2("-6,5.5");
|
||||||
EXPECT_FLOAT_EQ(vect2.x(), -6.0);
|
EXPECT_FLOAT_EQ(vect2.x(), -6.0);
|
||||||
EXPECT_FLOAT_EQ(vect2.y(), 5.5);
|
EXPECT_FLOAT_EQ(vect2.y(), 5.5);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user