[DEV] continue integration of etest and no-stl

This commit is contained in:
Edouard DUPIN 2017-09-05 23:07:32 +02:00
parent fa443fd991
commit a41ea2d0fa
40 changed files with 1163 additions and 234 deletions

13
etest/debug.cpp Normal file
View File

@ -0,0 +1,13 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etest/debug.hpp>
int32_t etest::getLogId() {
static int32_t g_val = elog::registerInstance("etest");
return g_val;
}

52
etest/debug.hpp Normal file
View File

@ -0,0 +1,52 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <elog/log.hpp>
namespace etest {
int32_t getLogId();
};
#define ETEST_BASE(info,data) ELOG_BASE(etest::getLogId(),info,data)
#define ETEST_PRINT(data) ETEST_BASE(-1, data)
#define ETEST_CRITICAL(data) ETEST_BASE(1, data)
#define ETEST_ERROR(data) ETEST_BASE(2, data)
#define ETEST_WARNING(data) ETEST_BASE(3, data)
#ifdef DEBUG
#define ETEST_INFO(data) ETEST_BASE(4, data)
#define ETEST_DEBUG(data) ETEST_BASE(5, data)
#define ETEST_VERBOSE(data) ETEST_BASE(6, data)
#define ETEST_TODO(data) ETEST_BASE(4, "TODO : " << data)
#else
#define ETEST_INFO(data) do { } while(false)
#define ETEST_DEBUG(data) do { } while(false)
#define ETEST_VERBOSE(data) do { } while(false)
#define ETEST_TODO(data) do { } while(false)
#endif
#define ETEST_HIDDEN(data) do { } while(false)
#ifdef DEBUG
#define ETEST_CHECK_INOUT(condition) \
do { \
if (!(condition)) { \
ETEST_ERROR("Wrong condition : " #condition); \
} \
} while (0)
#else
#define ETEST_CHECK_INOUT(condition) do { } while(false)
#endif
#define ETEST_ASSERT(condition,data) \
do { \
if (!(condition)) { \
ETEST_CRITICAL(data); \
assert(!#condition); \
} \
} while (0)

258
etest/etest.cpp Normal file
View File

@ -0,0 +1,258 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etest/etest.hpp>
#include <etest/debug.hpp>
#include <etk/Vector.hpp>
#include <elog/elog.hpp>
#include <echrono/Steady.hpp>
#include <echrono/Duration.hpp>
static int32_t nbTimeInit = 0;
static etk::Vector<etest::GenericTest*>& getListOfTest() {
static etk::Vector<etest::GenericTest*> s_listOfData;
return s_listOfData;
}
static etk::String filterGroup;
static etk::String filterTest;
void etest::unInit() {
if (nbTimeInit > 1) {
nbTimeInit--;
// not the time to un-init
return;
}
nbTimeInit--;
if (nbTimeInit < 0) {
ETEST_ERROR("ETEST system un-init More un-init than init ...");
nbTimeInit = 0;
return;
}
ETEST_INFO("ETEST system un-init (BEGIN)");
ETEST_INFO("ETEST system un-init (END)");
elog::unInit();
}
static etk::Vector<etk::String> getListGroupSpecific(const etk::Vector<etest::GenericTest*>& _value) {
etk::Vector<etk::String> listGroup;
for (auto &it: _value) {
if (etk::isIn(it->getTestGroup(), listGroup) == true) {
continue;
}
listGroup.pushBack(it->getTestGroup());
}
return listGroup;
}
static etk::Vector<etk::String> getListGroup() {
return getListGroupSpecific(getListOfTest());
}
static etk::Vector<etest::GenericTest*> getListFiltered() {
if (filterGroup == "") {
return getListOfTest();
}
etk::Vector<etest::GenericTest*> out;
for (auto &it: getListOfTest()) {
if (it->getTestGroup() != filterGroup) {
continue;
}
if (filterTest == "") {
out.pushBack(it);
continue;
}
if (filterTest == it->getTestName()) {
out.pushBack(it);
continue;
}
}
return out;
}
static void listAllTest() {
ETEST_ERROR("We have " << getListOfTest().size() << " tests:");
etk::Vector<etk::String> listGroup = getListGroup();
for (auto &itGroup: listGroup) {
ETEST_PRINT("Group: " << itGroup);
for (auto &it: getListOfTest()) {
if (it->getTestGroup() == itGroup) {
ETEST_PRINT(" - " << itGroup << "." << it->getTestName());
}
}
}
}
void etest::init(int32_t _argc, const char** _argv) {
if (nbTimeInit > 0) {
nbTimeInit++;
// already init
return;
}
nbTimeInit++;
elog::init(_argc, _argv);
ETEST_INFO("ETEST system init (BEGIN) ");
for (int32_t iii=0; iii<_argc ; ++iii) {
etk::String data = _argv[iii];
ETEST_PRINT("Parameter : " << data << " " << data.startWith("--etest-filter="));
if ( data == "-h"
|| data == "--help") {
ETEST_PRINT("etest - help : ");
if (_argc >= 1) {
ETEST_PRINT(" " << _argv[0] << " [options]");
ETEST_PRINT(" --etest-list List all test names");
ETEST_PRINT(" --etest-filter=XXX filter group or test: XXX or WWW.yyy");
}
ETEST_PRINT(" -h/--help: this help");
} else if (data == "--etest-list") {
listAllTest();
exit(0);
} else if (data.startWith("--etest-filter=") == true) {
etk::String filter = &data[15];
ETEST_PRINT(" Filter: " << filter);
ETEST_ERROR("plop:" << filter);
etk::Vector<etk::String> tmp = filter.split(".");
if (tmp.size() == 1) {
// Filter only the groups
filterGroup = filter;
} else if (tmp.size() == 2) {
filterGroup = tmp[0];
filterTest = tmp[1];
} else {
ETEST_CRITICAL("Can not parse the argument : '" << data << "' ==> more than 1 '.'");
}
} else if (data.startWith("--etest") == true) {
ETEST_ERROR("Can not parse the argument : '" << data << "'");
}
}
ETEST_INFO("ETEST system init (END)");
}
etest::GenericTest::GenericTest(const char* _file,
uint32_t _line,
const char* _testGroup,
const char* _testName):
m_file(_file),
m_line(_line),
m_testGroup(_testGroup),
m_testName(_testName) {
}
const etk::String& etest::GenericTest::getFileName() const {
return m_file;
}
uint32_t etest::GenericTest::getFileLine() const {
return m_line;
}
const etk::String& etest::GenericTest::getTestGroup() const {
return m_testGroup;
}
const etk::String& etest::GenericTest::getTestName() const {
return m_testName;
}
void etest::GenericTest::testEqual(bool _result, const char* _test1, const char* _test2) {
}
void etest::GenericTest::testNotEqual(bool _result, const char* _test1, const char* _test2) {
}
int32_t etest::runAllTest() {
etk::Vector<etest::GenericTest*> runList = getListFiltered();
etk::Vector<etk::String> listGroup = getListGroupSpecific(runList);
ETEST_PRINT("[==========] Running " << runList.size() << " tests from " << listGroup.size() << " test group.");
echrono::Steady tic = echrono::Steady::now();
for (auto &itGroup: listGroup) {
int32_t count = 0;
for (auto &it: getListOfTest()) {
if (it->getTestGroup() == itGroup) {
count++;
}
}
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << ":");
echrono::Steady ticGroup = echrono::Steady::now();
for (auto &it: getListOfTest()) {
if (it->getTestGroup() != itGroup) {
continue;
}
ETEST_PRINT("[ RUN ] " << itGroup << "." << it->getTestName());
it->clearLocal();
echrono::Steady ticTest = echrono::Steady::now();
it->run();
echrono::Steady tocTest = echrono::Steady::now();
ETEST_PRINT("[ OK ] " << itGroup << "." << it->getTestName() << " (" << (tocTest - ticTest) << ")");
}
echrono::Steady tocGroup = echrono::Steady::now();
ETEST_PRINT("[++++++++++] " << count << " test from " << itGroup << " (" << (tocGroup - ticGroup) << ")");
}
echrono::Steady toc = echrono::Steady::now();
ETEST_PRINT("[==========] All done in " << (toc - tic));
return -getListOfTest().size();
}
uint32_t etest::registerTest(etest::GenericTest* _element) {
if (_element == nullptr) {
return -1;
}
getListOfTest().pushBack(_element);
return getListOfTest().size()-1;
}
/*
7h55'30 [P] elog | Log in file: '/tmp/elog_etk-test.log'
[==========] Running 13 tests from 4 test cases.
[----------] Global test environment set-up.
[----------] 1 test from TestEtkColor
[ RUN ] TestEtkColor.RGBA8
[ OK ] TestEtkColor.RGBA8 (0 ms)
[----------] 1 test from TestEtkColor (0 ms total)
[----------] 1 test from TestEtkFSNode
[ RUN ] TestEtkFSNode.checkType
[ OK ] TestEtkFSNode.checkType (1 ms)
[----------] 1 test from TestEtkFSNode (1 ms total)
[----------] 8 tests from TestEtkHash
[ RUN ] TestEtkHash.Creation
[ OK ] TestEtkHash.Creation (0 ms)
[ RUN ] TestEtkHash.AddElement
[ OK ] TestEtkHash.AddElement (0 ms)
[ RUN ] TestEtkHash.OverWriteElement
[ OK ] TestEtkHash.OverWriteElement (0 ms)
[ RUN ] TestEtkHash.RemoveElement
[ OK ] TestEtkHash.RemoveElement (0 ms)
[ RUN ] TestEtkHash.ExistElement
[ OK ] TestEtkHash.ExistElement (0 ms)
[ RUN ] TestEtkHash.clear
[ OK ] TestEtkHash.clear (0 ms)
[ RUN ] TestEtkHash.getKey
[ OK ] TestEtkHash.getKey (0 ms)
[ RUN ] TestEtkHash.getKeys
[ OK ] TestEtkHash.getKeys (0 ms)
[----------] 8 tests from TestEtkHash (0 ms total)
[----------] 3 tests from TestSTDSharedPtr
[ RUN ] TestSTDSharedPtr.testBaseLocal
create Example [0]
Remove Example [0]
[ OK ] TestSTDSharedPtr.testBaseLocal (0 ms)
[ RUN ] TestSTDSharedPtr.testBaseShared
create Example [1]
Remove Example [1]
[ OK ] TestSTDSharedPtr.testBaseShared (0 ms)
[ RUN ] TestSTDSharedPtr.testBaseSharedDouble
create Example [2]
Remove Example [2]
[ OK ] TestSTDSharedPtr.testBaseSharedDouble (0 ms)
[----------] 3 tests from TestSTDSharedPtr (0 ms total)
[----------] Global test environment tear-down
[==========] 13 tests from 4 test cases ran. (2 ms total)
[ PASSED ] 13 tests.
*/

96
etest/etest.hpp Normal file
View File

@ -0,0 +1,96 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/String.hpp>
#define TEST_CLASS_NAME(groupName, localName) \
groupName##_##localName##_test
namespace etest {
class GenericTest {
private:
etk::String m_file;
uint32_t m_line;
etk::String m_testGroup;
etk::String m_testName;
public:
GenericTest(const char* _file,
uint32_t _line,
const char* _testGroup,
const char* _testName);
virtual ~GenericTest() = default;
const etk::String& getFileName() const;
uint32_t getFileLine() const;
const etk::String& getTestGroup() const;
const etk::String& getTestName() const;
void testEqual(bool _result, const char* _test1, const char* _test2);
void testNotEqual(bool _result, const char* _test1, const char* _test2);
void clearLocal() {};
virtual void run() = 0;
template<class ETEST_TYPE, class ETEST_TYPE_2>
void expectEq(const ETEST_TYPE& _element, const ETEST_TYPE_2& _result, const char* _elementChar, const char* _resultChar) {
bool res = (_element == _result);
testEqual(res, _elementChar, _resultChar);
}
};
void unInit();
void init(int32_t _argc, const char *_argv[]);
int32_t runAllTest();
uint32_t registerTest(etest::GenericTest* _element);
}
#define TEST(groupName,localName) \
class TEST_CLASS_NAME(groupName, localName) : public etest::GenericTest { \
protected: \
static uint32_t registerElement; \
public: \
TEST_CLASS_NAME(groupName, localName)() : \
etest::GenericTest(__FILE__, __LINE__, #groupName, #localName) { \
\
} \
void run() override; \
}; \
\
uint32_t TEST_CLASS_NAME(groupName, localName)::registerElement = etest::registerTest(new TEST_CLASS_NAME(groupName, localName)); \
\
void TEST_CLASS_NAME(groupName, localName)::run()
#define RUN_ALL_TESTS etest::runAllTest
#if 0
#define EXPECT_EQ(element, result) \
do { \
bool res = (element) == (result); \
testEqual(res, "##element##", "##result##"); \
} while (false)
#else
#define EXPECT_EQ(element, result) \
do { \
expectEq(element, result, "##element##", "##result##"); \
} while (false)
#endif
#define EXPECT_NE(element, result) \
do { \
bool res = (element) != (result); \
testNotEqual(res, "##element##", "##result##"); \
} while (false)
#define EXPECT_FLOAT_EQ(element, result) \
do { \
float res2 = (element) - (result); \
bool res = false; \
if (res2 < 0.00001f && res2 > -0.00001f) { \
res = true; \
} \
testEqual(res, "##element##", "##result##"); \
} while (false)

26
etk/Allocator.cpp Normal file
View File

@ -0,0 +1,26 @@
/** @file
* @author Edouard DUPIN
* @copyright 2017, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
//#include <etk/types.hpp>
#include <stdlib.h>
/*
void* operator new (size_t size) {
return malloc(size);
}
void* operator new[] (size_t size) {
return malloc(size);
}
void operator delete (void* ptr) {
free(ptr);
}
void operator delete[] (void* ptr) {
free(ptr);
}
*/

View File

@ -7,98 +7,198 @@
#include <etk/types.hpp> #include <etk/types.hpp>
//#include <ememory/UniquePtr.hpp> //#include <ememory/UniquePtr.hpp>
//TODO: Mission commando
#pragma once #pragma once
namespace etk { namespace etk {
template <typename ETK_TYPE_FUNCTION>
class FunctionPrivateSpecific;
template <typename ETK_TYPE_FUNCTION>
class FunctionPrivate;
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
class FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
public:
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() {
return nullptr;
}
};
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
class FunctionPrivateSpecific<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)(char*, ETK_TYPE_FUNCTION_ARGS&&...);
typedef void (*construct_fn_t)(char*, char*);
typedef void (*destroy_fn_t)(char*);
// type-aware generic functions for invoking
// the specialization of these functions won't be capable with
// the above function pointer types, so we need some cast
template <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)...);
}
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
static void construct_fn(ETK_TYPE_FUNCTION_FUNCTOR* _constructDestination,
ETK_TYPE_FUNCTION_FUNCTOR* _constructSource) {
// the functor type must be copy-constructible
new (_constructDestination) ETK_TYPE_FUNCTION_FUNCTOR(*_constructSource);
}
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;
construct_fn_t construct_f;
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
char* m_dataPointer;
size_t m_dataSize;
public:
FunctionPrivateSpecific():
invoke_f(nullptr),
construct_f(nullptr),
destroy_f(nullptr),
m_dataPointer(nullptr),
m_dataSize(0) {
}
FunctionPrivateSpecific(etk::NullPtr):
invoke_f(nullptr),
construct_f(nullptr),
destroy_f(nullptr),
m_dataPointer(nullptr),
m_dataSize(0) {
}
// 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_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR)) {
m_dataPointer = new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)];
// copy the functor to internal storage
construct_f(m_dataPointer, reinterpret_cast<char*>(&_functor));
}
// 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);
}
}
*/
~FunctionPrivateSpecific() {
if (m_dataPointer != nullptr) {
destroy_f(m_dataPointer);
delete m_dataPointer;
}
}
// 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)...);
}
bool operator!= (etk::NullPtr) const {
return m_dataPointer != nullptr;
}
bool operator== (etk::NullPtr) const {
return m_dataPointer == nullptr;
}
};
template <typename ETK_TYPE_FUNCTION> template <typename ETK_TYPE_FUNCTION>
class Function; class Function;
template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS> template <typename ETK_TYPE_FUNCTION_RETURN, typename... ETK_TYPE_FUNCTION_ARGS>
class Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> { class Function<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)> {
// function pointer types for the type-erasure behaviors private:
// all these char* parameters are actually casted from some functor type FunctionPrivate<ETK_TYPE_FUNCTION_RETURN(ETK_TYPE_FUNCTION_ARGS...)>* m_pointerPrivate;
typedef ETK_TYPE_FUNCTION_RETURN (*invoke_fn_t)(char*, ETK_TYPE_FUNCTION_ARGS&&...);
typedef void (*construct_fn_t)(char*, char*); public:
typedef void (*destroy_fn_t)(char*); Function():
// type-aware generic functions for invoking m_pointerPrivate(nullptr) {
// 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::move<ETK_TYPE_FUNCTION_ARGS>(_args)...);
}
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
static void construct_fn(ETK_TYPE_FUNCTION_FUNCTOR* _constructDestination,
ETK_TYPE_FUNCTION_FUNCTOR* _constructSource) {
// the functor type must be copy-constructible
new (_constructDestination) Function(*_constructSource);
}
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
static void destroy_fn(ETK_TYPE_FUNCTION_FUNCTOR* _functor) {
_functor->~Function();
}
// These pointers are storing behaviors.
invoke_fn_t invoke_f;
construct_fn_t construct_f;
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
char* m_dataPointer;
size_t m_dataSize;
public:
Function()
: invoke_f(nullptr)
, construct_f(nullptr)
, destroy_f(nullptr)
, m_dataPointer(nullptr)
, m_dataSize(0)
{}
// construct from any functor type
template <typename ETK_TYPE_FUNCTION_FUNCTOR>
Function(ETK_TYPE_FUNCTION_FUNCTOR _functor):
// specialize functions and erase their type info by casting
invoke_f(reinterpret_cast<invoke_fn_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(new char[sizeof(ETK_TYPE_FUNCTION_FUNCTOR)]),
m_dataSize(sizeof(ETK_TYPE_FUNCTION_FUNCTOR)) {
// copy the functor to internal storage
construct_f(m_dataPointer, reinterpret_cast<char*>(&_functor));
}
// copy constructor
Function(Function const& _obj):
invoke_f(_obj.invoke_f),
construct_f(_obj.construct_f),
destroy_f(_obj.destroy_f),
m_dataSize(_obj.m_dataSize) {
if (invoke_f) {
// when the source is not a null function, copy its internal functor
delete(m_dataPointer);
m_dataPointer = new char[m_dataSize];
construct_f(m_dataPointer, _obj.m_dataPointer);
} }
} Function(etk::NullPtr):
~Function() { m_pointerPrivate(nullptr) {
if (m_dataPointer != nullptr) {
destroy_f(m_dataPointer); }
delete m_dataPointer; // 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) {
if (_obj.m_pointerPrivate != nullptr) {
m_pointerPrivate = _obj.m_pointerPrivate->copy();
}
}
// copy constructor
Function(Function&& _obj):
m_pointerPrivate(etk::move(_obj.m_pointerPrivate)) {
}
~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;
}
Function& operator= (const Function& _obj) {
delete m_pointerPrivate;
m_pointerPrivate = nullptr;
if (_obj.m_pointerPrivate != nullptr) {
m_pointerPrivate = _obj.m_pointerPrivate->copy();
}
return *this;
}
Function& operator= (Function&& _obj) {
delete m_pointerPrivate;
m_pointerPrivate = etk::move(_obj.m_pointerPrivate);
return *this;
} }
}
// other constructors, from nullptr, from function pointers
ETK_TYPE_FUNCTION_RETURN operator()(ETK_TYPE_FUNCTION_ARGS... _args) {
return invoke_f(m_dataPointer,
etk::move<ETK_TYPE_FUNCTION_ARGS>(_args)...);
}
bool operator!= (nullptr_t) const {
return m_dataPointer != nullptr;
}
bool operator== (nullptr_t) const {
return m_dataPointer == nullptr;
}
}; };
} }
/* /*
// examples // examples
int main() int main()

View File

@ -449,7 +449,7 @@ bool etk::String::startWith(const etk::String& _val, bool _caseSensitive) const
} }
if (_caseSensitive == true) { if (_caseSensitive == true) {
for( size_t iii = 0; for( size_t iii = 0;
iii < size(); iii < size()-1;
iii++) { iii++) {
if (m_data[iii] != _val[iii]) { if (m_data[iii] != _val[iii]) {
return false; return false;
@ -458,7 +458,7 @@ bool etk::String::startWith(const etk::String& _val, bool _caseSensitive) const
return true; return true;
} }
for( size_t iii = 0; for( size_t iii = 0;
iii < _val.size(); iii < _val.size()-1;
iii++) { iii++) {
if (etk::toLower(_val[iii]) != etk::toLower(m_data[iii])) { if (etk::toLower(_val[iii]) != etk::toLower(m_data[iii])) {
return false; return false;

View File

@ -797,9 +797,7 @@ namespace etk {
bool swapped = false; bool swapped = false;
for (size_t jjj=_start; jjj<_stop - (iii+1); ++jjj) { for (size_t jjj=_start; jjj<_stop - (iii+1); ++jjj) {
if (_comparator(m_data[jjj], m_data[jjj+1]) == true) { if (_comparator(m_data[jjj], m_data[jjj+1]) == true) {
ETK_VECTOR_TYPE tmp = etk::move(m_data[jjj]); etk::swap(m_data[jjj], m_data[jjj+1]);
m_data[jjj+1] = etk::move(m_data[jjj]);
m_data[jjj+1] = etk::move(tmp);
swapped = true; swapped = true;
} }
} }

View File

@ -13,7 +13,7 @@ static const etk::ArchiveContent g_error;
const etk::String& etk::Archive::getName(size_t _id) const { const etk::String& etk::Archive::getName(size_t _id) const {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
size_t id = 0; size_t id = 0;
for (auto &it : m_content) { for (auto &it : m_content) {
if (id == _id) { if (id == _id) {
@ -26,7 +26,7 @@ const etk::String& etk::Archive::getName(size_t _id) const {
} }
const etk::ArchiveContent& etk::Archive::getContent(size_t _id) const { const etk::ArchiveContent& etk::Archive::getContent(size_t _id) const {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
size_t id = 0; size_t id = 0;
for (auto &it : m_content) { for (auto &it : m_content) {
if (id == _id) { if (id == _id) {
@ -38,7 +38,7 @@ const etk::ArchiveContent& etk::Archive::getContent(size_t _id) const {
} }
const etk::ArchiveContent& etk::Archive::getContent(const etk::String& _key) const { const etk::ArchiveContent& etk::Archive::getContent(const etk::String& _key) const {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
auto it = m_content.find(_key); auto it = m_content.find(_key);
if (it == m_content.end()) { if (it == m_content.end()) {
return g_error; return g_error;
@ -48,12 +48,12 @@ const etk::ArchiveContent& etk::Archive::getContent(const etk::String& _key) con
bool etk::Archive::exist(const etk::String& _key) const { bool etk::Archive::exist(const etk::String& _key) const {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
return m_content.find(_key) != m_content.end(); return m_content.find(_key) != m_content.end();
} }
void etk::Archive::display() { void etk::Archive::display() {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
for (auto &it : m_content) { for (auto &it : m_content) {
int32_t size = it.second.getTheoricSize(); int32_t size = it.second.getTheoricSize();
int32_t sizeR = it.second.size(); int32_t sizeR = it.second.size();
@ -112,7 +112,7 @@ etk::Archive* etk::Archive::loadPackage(const etk::String& _fileName) {
void etk::Archive::open(const etk::String& _key) { void etk::Archive::open(const etk::String& _key) {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
auto it = m_content.find(_key); auto it = m_content.find(_key);
if (it == m_content.end()) { if (it == m_content.end()) {
TK_ERROR("Try open an unexistant file : '" << _key << "'"); TK_ERROR("Try open an unexistant file : '" << _key << "'");
@ -126,7 +126,7 @@ void etk::Archive::open(const etk::String& _key) {
} }
void etk::Archive::close(const etk::String& _key) { void etk::Archive::close(const etk::String& _key) {
std::unique_lock<std::mutex> lock(m_mutex); ethread::UniqueLock lock(m_mutex);
auto it = m_content.find(_key); auto it = m_content.find(_key);
if (it == m_content.end()) { if (it == m_content.end()) {
TK_ERROR("Try close an unexistant file : '" << _key << "'"); TK_ERROR("Try close an unexistant file : '" << _key << "'");

View File

@ -10,7 +10,7 @@
#pragma once #pragma once
#include <etk/Map.hpp> #include <etk/Map.hpp>
#include <mutex> #include <ethread/Mutex.hpp>
#include <ememory/memory.hpp> #include <ememory/memory.hpp>
#include <etk/String.hpp> #include <etk/String.hpp>
@ -90,7 +90,7 @@ namespace etk {
*/ */
class Archive { class Archive {
private: private:
mutable std::mutex m_mutex; //!< access mutex (mini-zip does not support multiple access) mutable ethread::Mutex m_mutex; //!< access mutex (mini-zip does not support multiple access)
public: public:
/** /**
* @brief Contructor of the archive element * @brief Contructor of the archive element

View File

@ -6,7 +6,10 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/math/Vector2D.hpp> #include <etk/math/Vector2D.hpp>
#include <cmath>
extern "C" {
#include <math.h>
}
namespace etk { namespace etk {
/** /**

View File

@ -6,7 +6,10 @@
#pragma once #pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>
#include <cmath>
extern "C" {
#include <math.h>
}
namespace etk { namespace etk {
/** /**

View File

@ -10,7 +10,9 @@
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>
#include <cmath> extern "C" {
#include <math.h>
}
namespace etk { namespace etk {
/** /**

View File

@ -7,7 +7,9 @@
#include <etk/types.hpp> #include <etk/types.hpp>
#include <cmath> extern "C" {
#include <math.h>
}
#include <etk/math/Matrix3x3.hpp> #include <etk/math/Matrix3x3.hpp>
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>

View File

@ -4,14 +4,15 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#pragma once
#include <etk/types.hpp> #include <etk/types.hpp>
#include <etk/debug.hpp> #include <etk/debug.hpp>
#include <etk/UString.hpp> #include <etk/UString.hpp>
#include <etk/String.hpp> #include <etk/String.hpp>
#pragma once extern "C" {
#include <math.h>
#include <cmath> }
#ifdef ETK_BUILD_LINEARMATH #ifdef ETK_BUILD_LINEARMATH
#include <LinearMath/btScalar.h> #include <LinearMath/btScalar.h>

View File

@ -7,7 +7,9 @@
#include <etk/types.hpp> #include <etk/types.hpp>
#include <cmath> extern "C" {
#include <math.h>
}
#ifdef ETK_BUILD_LINEARMATH #ifdef ETK_BUILD_LINEARMATH
#include <LinearMath/btScalar.h> #include <LinearMath/btScalar.h>
#include <LinearMath/btMinMax.h> #include <LinearMath/btMinMax.h>

View File

@ -5,6 +5,7 @@
*/ */
#pragma once #pragma once
#include <etk/typeTrait.hpp>
namespace etk { namespace etk {
template<class ETK_MOVE_TYPE> template<class ETK_MOVE_TYPE>
@ -35,35 +36,15 @@ namespace etk {
_obj2 = etk::move(tmp); _obj2 = etk::move(tmp);
} }
template<class ETK_TYPE, ETK_TYPE v>
struct integralConstant {
static constexpr ETK_TYPE value = v;
typedef ETK_TYPE typeValue;
// using injected-class-name
typedef integralConstant type;
constexpr operator typeValue() const noexcept {
return value;
}
constexpr typeValue operator()() const noexcept {
return value;
}
};
typedef etk::integralConstant<bool, true> typeTrue;
typedef etk::integralConstant<bool, false> typeFalse;
template<class ETK_TYPE>
struct isLeftValueReference : etk::typeFalse {};
template<class ETK_TYPE>
struct isLeftValueReference<ETK_TYPE&> : etk::typeTrue {};
template <class ETK_FORWARD_TYPE> template <class ETK_FORWARD_TYPE>
inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type& _obj) noexcept { inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type& _obj) noexcept {
return static_cast<ETK_FORWARD_TYPE&&>(_obj); return static_cast<ETK_FORWARD_TYPE&&>(_obj);
} }
template <class ETK_FORWARD_TYPE> template <class ETK_FORWARD_TYPE>
inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type&& _obj) noexcept { inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type&& _obj) noexcept {
static_assert(!etk::isLeftValueReference<ETK_FORWARD_TYPE>::type, "Can not forward an rvalue as an lvalue."); static_assert(!etk::IsLeftValueReference<ETK_FORWARD_TYPE>::type, "Can not forward a right value as a left value.");
return static_cast<ETK_FORWARD_TYPE&&>(_obj); return static_cast<ETK_FORWARD_TYPE&&>(_obj);
} }
} }

View File

@ -12,7 +12,7 @@
#include <etk/tool.hpp> #include <etk/tool.hpp>
#include <etk/debug.hpp> #include <etk/debug.hpp>
#include <etk/Map.hpp> #include <etk/Map.hpp>
#include <mutex> #include <ethread/Mutex.hpp>
#ifdef __TARGET_OS__Windows #ifdef __TARGET_OS__Windows
#include <tchar.h> #include <tchar.h>
#include <iostream> #include <iostream>
@ -279,8 +279,8 @@ static etk::String FSNODE_LOCAL_join(const etk::String& _path1, const etk::Strin
} }
static std::mutex& getNodeMutex() { static ethread::Mutex& getNodeMutex() {
static std::mutex g_nodeMutex; static ethread::Mutex g_nodeMutex;
return g_nodeMutex; return g_nodeMutex;
} }
@ -323,7 +323,7 @@ etk::String etk::FSNodeGetHomePath() {
static etk::Archive* s_APKArchive = nullptr; static etk::Archive* s_APKArchive = nullptr;
static void loadAPK(const etk::String& _apkPath) { static void loadAPK(const etk::String& _apkPath) {
#ifdef __TARGET_OS__Android #ifdef __TARGET_OS__Android
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
TK_INFO("Loading APK '" << _apkPath << "'"); TK_INFO("Loading APK '" << _apkPath << "'");
s_APKArchive = etk::Archive::load(_apkPath); s_APKArchive = etk::Archive::load(_apkPath);
TK_ASSERT(s_APKArchive != nullptr, "Error loading APK ... '" << _apkPath << "'"); TK_ASSERT(s_APKArchive != nullptr, "Error loading APK ... '" << _apkPath << "'");
@ -363,7 +363,7 @@ etk::String etk::FSNodeGetHomePath() {
void etk::setBaseFolderData(const char* _folder, const char* _applName) { void etk::setBaseFolderData(const char* _folder, const char* _applName) {
#ifdef __TARGET_OS__Android #ifdef __TARGET_OS__Android
{ {
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
baseFolderData = "assets/"; baseFolderData = "assets/";
if (_applName != nullptr) { if (_applName != nullptr) {
baseFolderData += _applName; baseFolderData += _applName;
@ -379,7 +379,7 @@ void etk::setBaseFolderData(const char* _folder, const char* _applName) {
} }
void etk::setBaseFolderDataUser(const char* _folder) { void etk::setBaseFolderDataUser(const char* _folder) {
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
#ifdef __TARGET_OS__Android #ifdef __TARGET_OS__Android
baseFolderDataUser = _folder; baseFolderDataUser = _folder;
TK_INFO("baseFolderDataUser : '" << baseFolderDataUser << "'"); TK_INFO("baseFolderDataUser : '" << baseFolderDataUser << "'");
@ -389,7 +389,7 @@ void etk::setBaseFolderDataUser(const char* _folder) {
} }
void etk::setBaseFolderCache(const char* _folder) { void etk::setBaseFolderCache(const char* _folder) {
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
#ifdef __TARGET_OS__Android #ifdef __TARGET_OS__Android
baseFolderCache = _folder; baseFolderCache = _folder;
TK_INFO("baseFolderCache : '" << baseFolderCache << "'"); TK_INFO("baseFolderCache : '" << baseFolderCache << "'");
@ -400,7 +400,7 @@ void etk::setBaseFolderCache(const char* _folder) {
etk::String l_argZero = ""; etk::String l_argZero = "";
void etk::setArgZero(const etk::String& _val) { void etk::setArgZero(const etk::String& _val) {
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
l_argZero = _val; l_argZero = _val;
// set defaiult application name ... // set defaiult application name ...
etk::Vector<etk::String> elems = etk::split(_val, '/'); etk::Vector<etk::String> elems = etk::split(_val, '/');
@ -655,7 +655,7 @@ etk::String etk::getUserRunFolder() {
#ifdef HAVE_ZIP_DATA #ifdef HAVE_ZIP_DATA
bool etk::FSNode::loadDataZip() { bool etk::FSNode::loadDataZip() {
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
if (s_APKArchive == nullptr) { if (s_APKArchive == nullptr) {
return false; return false;
} }
@ -1871,7 +1871,7 @@ bool etk::FSNode::fileOpenRead() {
if (loadDataZip() == false) { if (loadDataZip() == false) {
return false; return false;
} }
std::unique_lock<std::mutex> lock(getNodeMutex()); ethread::UniqueLock lock(getNodeMutex());
s_APKArchive->open(m_systemFileName); s_APKArchive->open(m_systemFileName);
return m_zipContent->getTheoricSize() == m_zipContent->size(); return m_zipContent->getTheoricSize() == m_zipContent->size();
} }

View File

@ -8,7 +8,7 @@
#pragma once #pragma once
#include <mutex> #include <ethread/Mutex.hpp>
#include <etk/Vector.hpp> #include <etk/Vector.hpp>
#include <condition_variable> #include <condition_variable>
@ -20,7 +20,7 @@ namespace etk {
*/ */
template<class MY_TYPE=int32_t> class Fifo { template<class MY_TYPE=int32_t> class Fifo {
private : private :
std::mutex m_mutex; //!< protection of the internal data. ethread::Mutex m_mutex; //!< protection of the internal data.
std::condition_variable m_condition; //!< Message system to send event on an other thread. std::condition_variable m_condition; //!< Message system to send event on an other thread.
etk::Vector<MY_TYPE> m_data; //!< List of all message to send etk::Vector<MY_TYPE> m_data; //!< List of all message to send
public : public :
@ -43,7 +43,7 @@ namespace etk {
* @return false No data found or closed fifo * @return false No data found or closed fifo
*/ */
bool wait(MY_TYPE &_data) { bool wait(MY_TYPE &_data) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
// Check if data is not previously here // Check if data is not previously here
while(m_data.size() == 0) { while(m_data.size() == 0) {
m_condition.wait(lock); m_condition.wait(lock);
@ -66,7 +66,7 @@ namespace etk {
* @return false No message found while time-out appear. * @return false No message found while time-out appear.
*/ */
bool wait(MY_TYPE &_data, uint32_t _timeOutInUs) { bool wait(MY_TYPE &_data, uint32_t _timeOutInUs) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
// Check if data is not previously here // Check if data is not previously here
while(m_data.size() == 0) { while(m_data.size() == 0) {
if (m_condition.wait_for(lock, std::chrono::microseconds(_timeOutInUs)) == std::cv_status::timeout) { if (m_condition.wait_for(lock, std::chrono::microseconds(_timeOutInUs)) == std::cv_status::timeout) {
@ -88,7 +88,7 @@ namespace etk {
* @return Number of message in the fifo. * @return Number of message in the fifo.
*/ */
int32_t count() { int32_t count() {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
int32_t nbElement = m_data.size(); int32_t nbElement = m_data.size();
return nbElement; return nbElement;
}; };
@ -97,7 +97,7 @@ namespace etk {
* @param[in] _data New data to add at the fifo. * @param[in] _data New data to add at the fifo.
*/ */
void post(MY_TYPE &_data) { void post(MY_TYPE &_data) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
m_data.pushBack(_data); m_data.pushBack(_data);
m_condition.notify_all(); m_condition.notify_all();
}; };
@ -106,7 +106,7 @@ namespace etk {
* @param[in] _data New data to add at the fifo. * @param[in] _data New data to add at the fifo.
*/ */
void post(const MY_TYPE &_data) { void post(const MY_TYPE &_data) {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
m_data.pushBack(_data); m_data.pushBack(_data);
m_condition.notify_all(); m_condition.notify_all();
}; };
@ -114,7 +114,7 @@ namespace etk {
* @brief Remove all the message in the fifo. * @brief Remove all the message in the fifo.
*/ */
void clean() { void clean() {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<ethread::Mutex> lock(m_mutex);
// remove data // remove data
m_data.clear(); m_data.clear();
m_condition.wait_for(lock, std::chrono::microseconds(0)); m_condition.wait_for(lock, std::chrono::microseconds(0));

View File

@ -1,35 +0,0 @@
#include <etk/stdTools.hpp>
namespace std {
etk::Stream& operator <<(etk::Stream& _os, const std::chrono::system_clock::time_point& _obj) {
std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>(_obj.time_since_epoch());
int64_t totalSecond = ns.count()/1000000000;
int64_t millisecond = (ns.count()%1000000000)/1000000;
int64_t microsecond = (ns.count()%1000000)/1000;
int64_t nanosecond = ns.count()%1000;
//_os << totalSecond << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
int32_t second = totalSecond % 60;
int32_t minute = (totalSecond/60)%60;
int32_t hour = (totalSecond/3600)%24;
int32_t day = (totalSecond/(24*3600))%365;
int32_t year = totalSecond/(24*3600*365);
_os << year << "y " << day << "d " << hour << "h" << minute << ":"<< second << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
return _os;
}
etk::Stream& operator <<(etk::Stream& _os, const std::chrono::steady_clock::time_point& _obj) {
std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>(_obj.time_since_epoch());
int64_t totalSecond = ns.count()/1000000000;
int64_t millisecond = (ns.count()%1000000000)/1000000;
int64_t microsecond = (ns.count()%1000000)/1000;
int64_t nanosecond = ns.count()%1000;
//_os << totalSecond << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
int32_t second = totalSecond % 60;
int32_t minute = (totalSecond/60)%60;
int32_t hour = (totalSecond/3600)%24;
int32_t day = (totalSecond/(24*3600))%365;
int32_t year = totalSecond/(24*3600*365);
_os << year << "y " << day << "d " << hour << "h" << minute << ":"<< second << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
return _os;
}
}

View File

@ -1,12 +1,2 @@
#pragma once
#include <etk/types.hpp>
#include <etk/Stream.hpp>
#include <chrono>
namespace etk {
etk::Stream& operator <<(etk::Stream& _os, const std::chrono::system_clock::time_point& _obj);
//! @not_in_doc
etk::Stream& operator <<(etk::Stream& _os, const std::chrono::steady_clock::time_point& _obj);
}

112
etk/typeTrait.hpp Normal file
View File

@ -0,0 +1,112 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL-2 (see license file)
*/
#pragma once
namespace etk {
template<class ETK_TYPE, ETK_TYPE val>
struct IntegralConstant {
static constexpr ETK_TYPE value = val;
typedef ETK_TYPE typeValue;
// using injected-class-name
typedef IntegralConstant type;
constexpr operator typeValue() const noexcept {
return value;
}
constexpr typeValue operator()() const noexcept {
return value;
}
};
typedef etk::IntegralConstant<bool, true> typeTrue;
typedef etk::IntegralConstant<bool, false> typeFalse;
template<class ETK_TYPE>
struct IsLeftValueReference:
etk::typeFalse {
};
template<class ETK_TYPE>
struct IsLeftValueReference<ETK_TYPE&>:
etk::typeTrue {
};
template<bool B, class ETK_TYPE = void>
struct EnableIf {
};
template<class ETK_TYPE>
struct EnableIf<true, ETK_TYPE> {
typedef ETK_TYPE type;
};
template<class ETK_TYPE, class ETK_TYPE_2>
struct IsSame :
etk::typeFalse {
};
template<class ETK_TYPE>
struct IsSame<ETK_TYPE, ETK_TYPE> :
etk::typeTrue {
};
template<class ETK_TYPE>
struct RemoveConst {
typedef ETK_TYPE type;
};
template<class ETK_TYPE>
struct RemoveConst<const ETK_TYPE> {
typedef ETK_TYPE type;
};
template<class ETK_TYPE>
struct RemoveVolatile {
typedef ETK_TYPE type;
};
template<class ETK_TYPE>
struct RemoveVolatile<volatile ETK_TYPE> {
typedef ETK_TYPE type;
};
template<class ETK_TYPE>
struct RemoveConstVolatile {
typedef typename etk::RemoveVolatile<typename etk::RemoveConst<ETK_TYPE>::type>::type type;
};
template<class ETK_TYPE>
struct IsVoid :
etk::IsSame<void, typename etk::RemoveConstVolatile<ETK_TYPE>::type> {
};
template<typename ETK_TYPE>
struct IsEnum:
public etk::IntegralConstant<bool, __is_enum(ETK_TYPE)> {
};
template<typename ETK_TYPE>
struct IsUnion:
public etk::IntegralConstant<bool, __is_union(ETK_TYPE)> {
};
template<typename ETK_TYPE>
struct IsClass:
public etk::IntegralConstant<bool, __is_class(ETK_TYPE)> {
};
template<typename ETK_TYPE, typename ETK_TYPE_DERIVED>
struct IsBaseOf:
public etk::IntegralConstant<bool, __is_base_of(ETK_TYPE, ETK_TYPE_DERIVED)> {
};
}

View File

@ -16,27 +16,44 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
} }
// in case of android error ... #ifndef size_t
#ifdef __TARGET_OS__Android using size_t=uint64_t;
#if __ANDROID_BOARD_ID__ <= 20 #endif
#ifndef __STDINT_LIMITS #ifndef INT8_MIN
#define INT8_MIN (-128) #define INT8_MIN (-128)
#define INT8_MAX (127) #endif
#define UINT8_MAX (255U) #ifndef INT8_MAX
#define INT8_MAX (127)
#define INT16_MIN (-32768) #endif
#define INT16_MAX (32767) #ifndef UINT8_MAX
#define UINT16_MAX (65535U) #define UINT8_MAX (255U)
#endif
#define INT32_MIN (-2147483647-1) #ifndef INT16_MIN
#define INT32_MAX (2147483647) #define INT16_MIN (-32768)
#define UINT32_MAX (4294967295U) #endif
#ifndef INT16_MAX
#define INT64_MIN (__INT64_C(-9223372036854775807)-1) #define INT16_MAX (32767)
#define INT64_MAX (__INT64_C(9223372036854775807)) #endif
#define UINT64_MAX (__UINT64_C(18446744073709551615)) #ifndef UINT16_MAX
#endif #define UINT16_MAX (65535U)
#endif #endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#ifndef INT64_MIN
#define INT64_MIN (__INT64_C(-9223372036854775807)-1)
#endif
#ifndef INT64_MAX
#define INT64_MAX (__INT64_C(9223372036854775807))
#endif
#ifndef UINT64_MAX
#define UINT64_MAX (__UINT64_C(18446744073709551615))
#endif #endif
#ifndef ETK_BUILD_LINEARMATH #ifndef ETK_BUILD_LINEARMATH
@ -71,6 +88,94 @@ extern "C" {
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#endif #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
};
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 { namespace etk {
template <class TYPE> const TYPE& min(const TYPE& _val1, const TYPE& _val2) { template <class TYPE> const TYPE& min(const TYPE& _val1, const TYPE& _val2) {
return (_val1 > _val2) ? _val2 : _val1; return (_val1 > _val2) ? _val2 : _val1;
@ -88,10 +193,6 @@ namespace etk {
template <class TYPE> const TYPE& avg(const TYPE& _min, const TYPE& _val, const TYPE& _max) { template <class TYPE> const TYPE& avg(const TYPE& _min, const TYPE& _val, const TYPE& _max) {
return etk::min(etk::max(_min,_val),_max); return etk::min(etk::max(_min,_val),_max);
} }
};
namespace etk {
template<class ETK_ITERATOR_TYPE> template<class ETK_ITERATOR_TYPE>
size_t distance(const ETK_ITERATOR_TYPE& _start, const ETK_ITERATOR_TYPE& _stop) { size_t distance(const ETK_ITERATOR_TYPE& _start, const ETK_ITERATOR_TYPE& _stop) {
size_t out = 0; size_t out = 0;
@ -105,4 +206,3 @@ namespace etk {
} }
#include <etk/move.hpp> #include <etk/move.hpp>
#include <etk/Stream.hpp> #include <etk/Stream.hpp>

52
lutin_etest.py Normal file
View File

@ -0,0 +1,52 @@
#!/usr/bin/python
import lutin.debug as debug
import lutin.tools as tools
def get_type():
return "LIBRARY"
def get_desc():
return "Ewol tool kit (test: test framework)"
def get_licence():
return "MPL-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return "authors.txt"
def get_version():
return "version.txt"
def configure(target, my_module):
my_module.add_extra_flags()
# add the file to compile:
my_module.add_src_file([
'etest/etest.cpp',
'etest/debug.cpp',
])
my_module.add_header_file([
'etest/etest.hpp',
])
# build in C++ mode
my_module.compile_version("c++", 2011)
# add dependency of the generic C++ library:
my_module.add_depend([
'etk-base',
'echrono',
'elog',
'cxx'
])
my_module.add_path(".")
return True

View File

@ -34,6 +34,7 @@ def configure(target, my_module):
'etk/stdTools.cpp', 'etk/stdTools.cpp',
'etk/Stream.cpp', 'etk/Stream.cpp',
'etk/Function.cpp', 'etk/Function.cpp',
'etk/Allocator.cpp',
]) ])
my_module.add_header_file([ my_module.add_header_file([
@ -48,6 +49,7 @@ def configure(target, my_module):
'etk/Pair.hpp', 'etk/Pair.hpp',
'etk/Map.hpp', 'etk/Map.hpp',
'etk/move.hpp', 'etk/move.hpp',
'etk/typeTrait.hpp',
'etk/Function.hpp', 'etk/Function.hpp',
]) ])

View File

@ -43,7 +43,7 @@ def configure(target, my_module):
]) ])
my_module.add_depend([ my_module.add_depend([
'etk', 'etk',
'gtest', 'etest',
'test-debug' 'test-debug'
]) ])
return True return True

View File

@ -13,15 +13,13 @@
#include <etk/String.hpp> #include <etk/String.hpp>
#include <etk/os/FSNode.hpp> #include <etk/os/FSNode.hpp>
#include <gtest/gtest.h> #include <etest/etest.hpp>
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
// init Google test : // init test engine:
::testing::InitGoogleTest(&argc, const_cast<char **>(argv)); etest::init(argc, argv);
// the only one init for etk: // the only one init for etk:
etk::init(argc, argv); etk::init(argc, argv);
etk::initDefaultFolder("ewolApplNoName"); etk::initDefaultFolder("ewolApplNoName");
//testRegExp();
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#define NAME "Archive" #define NAME "Archive"
#include <etk/archive/Archive.hpp> #include <etk/archive/Archive.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -1,12 +1,10 @@
/** /**
* @author Edouard DUPIN * @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved * @copyright 2011, Edouard DUPIN, all right reserved
*
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/Color.hpp> #include <etk/Color.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#define NAME "Color" #define NAME "Color"

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
#include <etk/os/FSNode.hpp> #include <etk/os/FSNode.hpp>
#define NAME "FSNode" #define NAME "FSNode"

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/Map.hpp> #include <etk/Map.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>
@ -21,10 +21,30 @@ TEST(TestEtkMap, add_ordered) {
etk::Map<uint32_t, etk::String> testData(0,true); etk::Map<uint32_t, etk::String> testData(0,true);
EXPECT_EQ(testData.size(), 0); EXPECT_EQ(testData.size(), 0);
testData.add(2, "a 2"); testData.add(2, "a 2");
TEST_INFO("--------------------");
for (size_t iii=0; iii<testData.size(); ++iii) {
TEST_INFO(" " << iii << " " << testData.getKey(iii));
}
testData.add(19, "b 19"); testData.add(19, "b 19");
TEST_INFO("--------------------");
for (size_t iii=0; iii<testData.size(); ++iii) {
TEST_INFO(" " << iii << " " << testData.getKey(iii));
}
testData.add(1, "c 1"); testData.add(1, "c 1");
TEST_INFO("--------------------");
for (size_t iii=0; iii<testData.size(); ++iii) {
TEST_INFO(" " << iii << " " << testData.getKey(iii));
}
testData.add(5, "d 5"); testData.add(5, "d 5");
TEST_INFO("--------------------");
for (size_t iii=0; iii<testData.size(); ++iii) {
TEST_INFO(" " << iii << " " << testData.getKey(iii));
}
testData.add(66, "e 66"); testData.add(66, "e 66");
TEST_INFO("--------------------");
for (size_t iii=0; iii<testData.size(); ++iii) {
TEST_INFO(" " << iii << " " << testData.getKey(iii));
}
EXPECT_EQ(testData.size(), 5); EXPECT_EQ(testData.size(), 5);
EXPECT_EQ(testData[1], "c 1"); EXPECT_EQ(testData[1], "c 1");
EXPECT_EQ(testData.getValue(0), "c 1"); EXPECT_EQ(testData.getValue(0), "c 1");

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/Map.hpp> #include <etk/Map.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/math/Matrix2x2.hpp> #include <etk/math/Matrix2x2.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>
#include <etk/math/Matrix3x3.hpp> #include <etk/math/Matrix3x3.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -4,7 +4,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/math/Quaternion.hpp> #include <etk/math/Quaternion.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -6,7 +6,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/RegEx.hpp> #include <etk/RegEx.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -4,7 +4,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/String.hpp> #include <etk/String.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

155
test/testTrait.cpp Normal file
View File

@ -0,0 +1,155 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etest/etest.hpp>
#include <etk/Color.hpp>
#include <test-debug/debug.hpp>
#define NAME "Color"
TEST(typeTrait, RemoveConstVolatile_1) {
typedef std::remove_cv<const int>::type type1;
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
}
TEST(typeTrait, RemoveConstVolatile_2) {
typedef std::remove_cv<volatile int>::type type1;
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
}
TEST(typeTrait, RemoveConstVolatile_3) {
typedef std::remove_cv<const volatile int>::type type1;
EXPECT_EQ(etk::IsSame<int, type1>::value, true);
}
TEST(typeTrait, RemoveConstVolatile_4) {
typedef std::remove_cv<const volatile int*>::type type1;
EXPECT_EQ(etk::IsSame<const volatile int*, type1>::value, true);
}
TEST(typeTrait, RemoveConstVolatile_5) {
typedef std::remove_cv<int* const volatile>::type type1;
EXPECT_EQ(etk::IsSame<int*, type1>::value, true);
}
TEST(typeTrait, IsVoid_1) {
EXPECT_EQ(etk::IsVoid<void>::value, true);
}
TEST(typeTrait, IsVoid_2) {
EXPECT_EQ(etk::IsVoid<int>::value, false);
}
class A {};
class B : A {};
class C {};
TEST(typeTrait, IsBaseOf_1) {
EXPECT_EQ(etk::IsBaseOf<A, B>::value, true);
}
TEST(typeTrait, IsBaseOf_2) {
EXPECT_EQ(etk::IsBaseOf<B, A>::value, false);
}
TEST(typeTrait, IsBaseOf_3) {
EXPECT_EQ(etk::IsBaseOf<C, B>::value, false);
}
TEST(typeTrait, IsBaseOf_4) {
EXPECT_EQ(etk::IsBaseOf<C, C>::value, true);
}
TEST(typeTrait, IsSame_1) {
EXPECT_EQ(etk::IsSame<int, int32_t>::value, true);
}
TEST(typeTrait, IsSame_2) {
EXPECT_EQ(etk::IsSame<int, int64_t>::value, false);
}
TEST(typeTrait, IsSame_3) {
EXPECT_EQ(etk::IsSame<float, int32_t>::value, false);
}
TEST(typeTrait, IsSame_4) {
EXPECT_EQ(etk::IsSame<int, int>::value, true);
}
TEST(typeTrait, IsSame_5) {
EXPECT_EQ(etk::IsSame<int, unsigned int>::value, false);
}
TEST(typeTrait, IsSame_6) {
EXPECT_EQ(etk::IsSame<int, signed int>::value, true);
}
TEST(typeTrait, IsSame_7) {
EXPECT_EQ(etk::IsSame<char, char>::value, true);
}
TEST(typeTrait, IsSame_8) {
EXPECT_EQ(etk::IsSame<char, unsigned char>::value, false);
}
TEST(typeTrait, IsSame_9) {
EXPECT_EQ(etk::IsSame<char, signed char>::value, false);
}
struct K_A {};
class K_B {};
enum class K_C {};
TEST(typeTrait, IsClass_1) {
EXPECT_EQ(etk::IsClass<K_A>::value, true);
}
TEST(typeTrait, IsClass_2) {
EXPECT_EQ(etk::IsClass<K_B>::value, true);
}
TEST(typeTrait, IsClass_3) {
EXPECT_EQ(etk::IsClass<K_C>::value, false);
}
TEST(typeTrait, IsClass_4) {
EXPECT_EQ(etk::IsClass<int>::value, false);
}
#include <iostream>
#include <type_traits>
struct J_A {};
typedef union {
int a;
float b;
} J_B;
struct J_C {
J_B d;
};
TEST(typeTrait, IsUnion_1) {
EXPECT_EQ(etk::IsUnion<K_A>::value, false);
}
TEST(typeTrait, IsUnion_2) {
EXPECT_EQ(etk::IsUnion<K_B>::value, true);
}
TEST(typeTrait, IsUnion_3) {
EXPECT_EQ(etk::IsUnion<K_C>::value, false);
}
TEST(typeTrait, IsUnion_4) {
EXPECT_EQ(etk::IsUnion<int>::value, false);
}

View File

@ -4,7 +4,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/math/Vector2D.hpp> #include <etk/math/Vector2D.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>

View File

@ -4,7 +4,7 @@
* @license MPL v2.0 (see license file) * @license MPL v2.0 (see license file)
*/ */
#include <gtest/gtest.h> #include <etest/etest.hpp>
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>
#include <test-debug/debug.hpp> #include <test-debug/debug.hpp>