[DEV] some correction and add etk::Set

This commit is contained in:
Edouard DUPIN 2017-09-20 01:10:57 +02:00
parent 027ebd8ae9
commit 4fe37acdf0
14 changed files with 856 additions and 35 deletions

432
etk/Set.hpp Normal file
View File

@ -0,0 +1,432 @@
/** @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/Pair.hpp>
#include <etk/Vector.hpp>
namespace etk {
/**
* @brief Set table template is a simple classical "Set" interface.
* A Set contain a list of sorted single element
* - 1 2 3 4 19 55 4356345
* - "aaa" "AABB" "ZZ"
*
* A simple example of use:
* @code{.cpp}
* // Create a integer Set table
* etk::Set<int> myValue;
* // add some element (note add and set is the same function)
* myValue.add(98837);
* myValue.set(88);
* // Display an element:
* printf("my value is : %d", myValue[2]);
* // Change value of an element:
* size_t position = myValue.set(99);
* // Remove an element:
* myValue.remove(99);
* //Clean all the table:
* myValue.clear();
* // number of elements:
* size_t size = myValue.size();
* @endcode
*/
template<class ETK_SET_TYPE>
class Set {
public:
class Iterator {
private:
size_t m_current; //!< current Id on the vector
Set<ETK_SET_TYPE>* m_set; //!< Pointer on the current element of the vectorBin
public:
/**
* @brief Basic iterator constructor with no link with an etk::Vector
*/
Iterator():
m_current(0),
m_set(nullptr) {
// nothing to do ...
}
/**
* @brief Recopy constructor on a specific etkVector.
* @param[in] _obj The Iterator that might be copy
*/
Iterator(const Iterator & _obj):
m_current(_obj.m_current),
m_set(_obj.m_set) {
// nothing to do ...
}
/**
* @brief Assignation operator.
* @param[in] _otherIterator The Iterator that might be copy
* @return reference on the current Iterator
*/
Iterator& operator=(const Iterator & _obj) {
m_current = _obj.m_current;
m_set = _obj.m_set;
return *this;
}
/**
* @brief Basic destructor
*/
~Iterator() {
m_current = 0;
m_set = nullptr;
}
/**
* @brief basic boolean cast
* @return true if the element is present in the etkVector size
*/
operator bool () {
return (m_current < m_set->size());
}
/**
* @brief Incremental operator
* @return Reference on the current iterator increment
*/
Iterator& operator++ () {
if ( m_set != nullptr
&& m_current < m_set->size() )
{
m_current++;
}
return *this;
}
/**
* @brief Decremental operator
* @return Reference on the current iterator decrement
*/
Iterator& operator-- () {
if ( m_set != nullptr
&& m_current > 0) {
m_current--;
}
return *this;
}
/**
* @brief Incremental operator
* @return Reference on a new iterator and increment the other one
*/
Iterator operator++ (int32_t) {
Iterator it(*this);
++(*this);
return it;
}
/**
* @brief Decremental operator
* @return Reference on a new iterator and decrement the other one
*/
Iterator operator-- (int32_t) {
Iterator it(*this);
--(*this);
return it;
}
Iterator& operator-= (size_t _offset) {
m_current -= _offset;
return *this;
}
Iterator operator- (size_t _offset) const {
Iterator tmp(*this);
tmp -= _offset;
return tmp;
}
Iterator& operator-= (int _offset) {
m_current -= _offset;
return *this;
}
Iterator operator- (int _offset) const {
Iterator tmp(*this);
tmp -= _offset;
return tmp;
}
Iterator& operator-= (int64_t _offset) {
m_current -= _offset;
return *this;
}
Iterator operator- (int64_t _offset) const {
Iterator tmp(*this);
tmp -= _offset;
return tmp;
}
Iterator& operator+= (size_t _offset) {
m_current += _offset;
return *this;
}
Iterator operator+ (size_t _offset) const {
Iterator tmp(*this);
tmp += _offset;
return tmp;
}
Iterator& operator+= (int _offset) {
m_current += _offset;
return *this;
}
Iterator operator+ (int _offset) const {
Iterator tmp(*this);
tmp += _offset;
return tmp;
}
Iterator& operator+= (int64_t _offset) {
m_current += _offset;
return *this;
}
Iterator operator+ (int64_t _offset) const {
Iterator tmp(*this);
tmp += _offset;
return tmp;
}
/**
* @brief Get reference on the current Element
* @return the reference on the current Element
*/
const ETK_SET_TYPE* operator-> () const {
//TK_CHECK_INOUT(m_current < m_set->size());
return &(*m_set)[m_current];
}
ETK_SET_TYPE* operator-> () {
//TK_CHECK_INOUT(m_current < m_set->size());
return &(*m_set)[m_current];
}
/**
* @brief Get reference on the current Element
* @return the reference on the current Element
*/
const ETK_SET_TYPE& operator* () const {
//TK_CHECK_INOUT(m_current < m_set->size());
return (*m_set)[m_current];
}
ETK_SET_TYPE& operator* () {
//TK_CHECK_INOUT(m_current < m_set->size());
return (*m_set)[m_current];
}
bool operator== (const Iterator& _obj) const{
return m_set == _obj.m_set
&& m_current == _obj.m_current;
}
bool operator!= (const Iterator& _obj) const {
return m_set != _obj.m_set
|| m_current != _obj.m_current;
}
private:
Iterator(const etk::Set<ETK_SET_TYPE> * _obj, int32_t _pos):
m_current(_pos),
m_set(const_cast<etk::Set<ETK_SET_TYPE>*>(_obj)) {
// nothing to do ...
}
size_t getCurrent() const {
return m_current;
}
friend class Set;
};
typedef bool (*sortFunction)(const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2);
private:
etk::Vector<ETK_SET_TYPE> m_data; //!< Data of the Set ==> the Set table is composed of pointer, this permit to have high speed when resize the vector ...
sortFunction m_comparator;
public:
/**
* @brief Set the comparator of the set.
* @param[in] _comparator comparing function.
*/
void setComparator(sortFunction _comparator) {
m_comparator = _comparator;
if (m_comparator != nullptr) {
m_data.sort(0, m_data.size(), m_comparator);
}
}
/**
* @brief Constructor of the Set table.
* @param[in] _count Number of basic element (pre-allocated) in the table.
*/
Set(int32_t _count = 0) :
m_data(_count),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
// nothing to do
}
/**
* @brief List initializer (ex: etk::Vector<etk::String> plop = {"hello", world"}
* @param[in] _element element to add in the vector
*/
template<typename... ETK_SET_TYPE_2>
Set(const ETK_SET_TYPE_2& ... _args):
m_data(0),
m_comparator([](const ETK_SET_TYPE& _key1, const ETK_SET_TYPE& _key2) { return _key1 < _key2; }) {
add(_args...);
}
/**
* @brief Destructor of the Set table (clear all element in the table)
*/
~Set() {
clear();
}
/**
* @brief Remove all entry in the Set table.
* @note It does not delete pointer if your value is a pointer type...
*/
void clear() {
m_data.clear();
}
/**
* @brief Check if an element exist or not
* @param[in] _key Name of the Set requested
* @return true if the element exist
*/
bool exist(const ETK_SET_TYPE& _key) const {
Iterator it = find(_key);
if (it == end()) {
return false;
}
return true;
}
/**
* @brief Get Element an a special position
* @param[in] _position Position in the Set
* @return An reference on the selected element
*/
ETK_SET_TYPE& operator[] (size_t _position) {
return m_data[_position];
}
/**
* @brief Get Element an a special position
* @param[in] _position Position in the Set
* @return An reference on the selected element
*/
const ETK_SET_TYPE& operator[] (size_t _position) const {
return m_data[_position];
}
private:
template<typename... ETK_SET_TYPE_2>
void add(const ETK_SET_TYPE& _value, const ETK_SET_TYPE_2& ... _args) {
add(_value);
add(_args...);
}
public:
/**
* @brief Add an element OR set an element value
* @note add and set is the same function.
* @param[in] _key Name of the value to set in the Set table.
* @param[in] _value Value to set in the Set table.
*/
void add(const ETK_SET_TYPE& _key) {
if (m_comparator != nullptr) {
for (size_t iii=0; iii<m_data.size(); ++iii) {
if (_key == m_data[iii]) {
return;
}
if (m_comparator(_key, m_data[iii]) == true) {
// Find a position
m_data.insert(iii, etk::move(_key));
return;
}
}
}
m_data.pushBack(etk::move(_key));
}
/**
* @brief Set an element value
* @note add and set is the same function.
* @param[in] _key Name of the value to set in the Set table.
* @param[in] _value Value to set in the Set table.
*/
void set(const ETK_SET_TYPE& _key) {
add(etk::move(_key));
}
/**
* @brief Remove an element in the Set table.
* @param[in] _key Name of the element to remove.
*/
/*
// TODO: this is dangerous ...
void erase(const ETK_SET_TYPE& _key) {
Iterator it = find(_key);
if (it == end()) {
return;
}
m_data.erase(m_data.begin() + it.getCurrent());
}
*/
/**
* @brief Remove an element in the Set table.
* @param[in] _it Iterator on the element.
*/
Iterator erase(const Iterator& _it) {
return position(*m_data.erase(m_data.begin() + _it.getCurrent()));
}
/**
* @brief Get the number of element in the Set table
* @return number of elements
*/
size_t size() const {
return m_data.size();
}
/**
* @brief Swap generic function
* @param[in,out] _obj Object to swap data & control...
*/
void swap(Set& _obj) {
etk::swap(m_data, _obj.m_data);
etk::swap(m_comparator, _obj.m_comparator);
}
/**
* @brief Get an iterator an an specific position
* @param[in] _pos Requested position of the iterator in the vector
* @return The Iterator
*/
Iterator position(size_t _pos) {
return Iterator(this, _pos);
}
const Iterator position(size_t _pos) const {
return Iterator(this, _pos);
}
/**
* @brief Get an Iterator on the start position of the Vector
* @return The Iterator
*/
Iterator begin() {
return position(0);
}
const Iterator begin() const {
return position(0);
}
/**
* @brief Get an Iterator on the end position of the Vector
* @return The Iterator
*/
Iterator end() {
return position(size());
}
const Iterator end() const {
return position(size());
}
/**
* @brief Find an element position the the Set table
* @param[in] _key Name of the element to find
* @return Iterator on the element find or end()
*/
const Iterator find(const ETK_SET_TYPE& _key) const {
// TODO: search in a dichotomic way.
for (size_t iii=0; iii<m_data.size(); iii++) {
if (m_data[iii] == _key) {
return position(iii);
}
}
return end();
}
Iterator find(const ETK_SET_TYPE& _key) {
// TODO: search in a dichotomic way.
for (size_t iii=0; iii<m_data.size(); iii++) {
if (m_data[iii] == _key) {
return position(iii);
}
}
return end();
}
};
}

View File

@ -1038,11 +1038,10 @@ namespace etk {
}
}
bool etk::operator> (const etk::String& _left, const etk::String& _right) {
for (size_t iii=0; iii<_left.size() && iii<_right.size(); ++iii) {
for (size_t iii=0;
iii<_left.size() && iii<_right.size();
++iii) {
if (_left[iii] > _right[iii]) {
return true;
}
@ -1056,7 +1055,9 @@ bool etk::operator> (const etk::String& _left, const etk::String& _right) {
return false;
}
bool etk::operator>= (const etk::String& _left, const etk::String& _right) {
for (size_t iii=0; iii<_left.size() && iii<_right.size(); ++iii) {
for (size_t iii=0;
iii<_left.size() && iii<_right.size();
++iii) {
if (_left[iii] > _right[iii]) {
return true;
}
@ -1070,7 +1071,9 @@ bool etk::operator>= (const etk::String& _left, const etk::String& _right) {
return false;
}
bool etk::operator< (const etk::String& _left, const etk::String& _right) {
for (size_t iii=0; iii<_left.size() && iii<_right.size(); ++iii) {
for (size_t iii=0;
iii<_left.size() && iii<_right.size();
++iii) {
if (_left[iii] < _right[iii]) {
return true;
}
@ -1084,7 +1087,9 @@ bool etk::operator< (const etk::String& _left, const etk::String& _right) {
return false;
}
bool etk::operator<= (const etk::String& _left, const etk::String& _right) {
for (size_t iii=0; iii<_left.size() && iii<_right.size(); ++iii) {
for (size_t iii=0;
iii<_left.size() && iii<_right.size();
++iii) {
if (_left[iii] < _right[iii]) {
return true;
}

View File

@ -205,6 +205,9 @@ namespace etk {
m_vector(const_cast<Vector<ETK_VECTOR_TYPE> *>(_obj)) {
// nothing to do ...
}
size_t getCurrent() const {
return m_current;
}
friend class Vector;
};
private:
@ -470,6 +473,7 @@ namespace etk {
m_data[idElement+iii] = _item[iii];
}
}
private:
void pushBackN(const ETK_VECTOR_TYPE& _value) {
pushBack(_value);
}
@ -478,6 +482,7 @@ namespace etk {
pushBack(_value);
pushBackN(_args...);
}
public:
/**
* @brief Remove the first element of the vector
*/
@ -509,7 +514,7 @@ namespace etk {
* @param[in] _nbElement Number of element to add in the Vector
*/
void insert(size_t _pos, const ETK_VECTOR_TYPE * _item, size_t _nbElement) {
if (_pos>m_size) {
if (_pos > m_size) {
//TK_WARNING(" can not insert Element at this position : " << _pos << " > " << m_size << " add it at the end ... ");
pushBack(_item, _nbElement);
return;
@ -517,14 +522,15 @@ namespace etk {
size_t idElement = m_size;
// Request resize of the current buffer
resize(m_size+_nbElement);
if (idElement>=m_size) {
if (idElement >= m_size) {
//TK_ERROR("Resize does not work correctly ... not added item");
return;
}
// move current data (after the position)
size_t sizeToMove = (idElement - _pos);
if ( 0 < sizeToMove) {
if (sizeToMove > 0) {
for (size_t iii=1; iii<=sizeToMove; iii++) {
// tODO: better explicite the swap...
m_data[m_size-iii] = etk::move(m_data[idElement-iii]);
}
}
@ -541,6 +547,14 @@ namespace etk {
void insert(size_t _pos, const ETK_VECTOR_TYPE& _item) {
insert(_pos, &_item, 1);
}
/**
* @brief Insert one element in the Vector at a specific position
* @param[in] _pos Position to add the elements.
* @param[in] _item Element to add.
*/
void insert(const Iterator& _pos, const ETK_VECTOR_TYPE& _item) {
insert(_pos.getCurrent(), _item);
}
/**
* @brief Remove N element
* @param[in] _pos Position to remove the data
@ -578,8 +592,8 @@ namespace etk {
* @return An iterator on the new element at this position.
*/
Iterator erase(const Iterator& _it) {
eraseLen(_it.m_current, 1);
return position(_it.m_current);
eraseLen(_it.getCurrent(), 1);
return position(_it.getCurrent());
}
/**
* @brief Remove one element
@ -613,6 +627,9 @@ namespace etk {
// Request resize of the current buffer
resize(m_size-nbElement);
}
void erase(const Iterator& _pos, const Iterator& _posEnd) {
erase(_pos.getCurrent(), _posEnd.getCurrent());
}
/**
* @brief extract data between two point :
* @param[in] _posStart start position to extract data

View File

@ -28,13 +28,18 @@ namespace etk {
return (typename etk::RemoveReference<ETK_MOVE_TYPE>::m_type&&)_obj;
}
template<typename ETK_SWAP_TYPE>
template<typename ETK_SWAP_TYPE,
typename etk::EnableIf<etk::Is_swap_MemberFunctionExists<ETK_SWAP_TYPE>::value,int>::type = 0>
inline void swap(ETK_SWAP_TYPE& _obj1, ETK_SWAP_TYPE& _obj2) {
_obj1.swap(_obj2);
}
template<typename ETK_SWAP_TYPE,
typename etk::EnableIf<!etk::Is_swap_MemberFunctionExists<ETK_SWAP_TYPE>::value,int>::type = 0>
inline void swap(ETK_SWAP_TYPE& _obj1, ETK_SWAP_TYPE& _obj2) {
ETK_SWAP_TYPE tmp = etk::move(_obj1);
_obj1 = etk::move(_obj2);
_obj2 = etk::move(tmp);
}
template <class ETK_FORWARD_TYPE>
inline ETK_FORWARD_TYPE&& forward(typename etk::RemoveReference<ETK_FORWARD_TYPE>::m_type& _obj) noexcept {
return static_cast<ETK_FORWARD_TYPE&&>(_obj);

View File

@ -28,6 +28,19 @@ namespace etk {
inline float sqrt(float _value) {
return ::sqrtf(_value);
}
inline float pow(float _xxx, float _yyy) {
return ::powf(_xxx, _yyy);
}
inline float log(float _value) {
return ::logf(_value);
}
inline float log10(float _value) {
return ::log10f(_value);
}
inline float exp(float _value) {
return ::expf(_value);
}
inline double cos(double _value) {
return ::cos(_value);
}
@ -49,6 +62,18 @@ namespace etk {
inline double sqrt(double _value) {
return ::sqrt(_value);
}
inline double pow(double _xxx, double _yyy) {
return ::pow(_xxx, _yyy);
}
inline double log(double _value) {
return ::log(_value);
}
inline double log10(double _value) {
return ::log10(_value);
}
inline double exp(double _value) {
return ::exp(_value);
}
template <class TYPE> const TYPE& min(const TYPE& _val1, const TYPE& _val2) {
return (_val1 > _val2) ? _val2 : _val1;
}
@ -72,7 +97,8 @@ namespace etk {
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) {
ETK_ITERATOR_TYPE tmp2 = _stop;
while (tmp != tmp2) {
out++;
++tmp;
}

View File

@ -12,21 +12,21 @@ extern "C" {
#include <stdlib.h>
}
double etk::tool::frand(double _a, double _b) {
double etk::random::frand(double _a, double _b) {
return (float)(( (double)rand()/(double)RAND_MAX ) * ((double)_b-(double)_a) + (double)_a);
}
int32_t etk::tool::irand(int32_t _a, int32_t _b) {
int32_t etk::random::irand(int32_t _a, int32_t _b) {
return (int32_t)(( rand()/(double)RAND_MAX ) * ((double)_b-(double)_a) + (double)_a);
}
uint32_t etk::tool::urand(uint32_t _a, uint32_t _b) {
uint32_t etk::random::urand(uint32_t _a, uint32_t _b) {
return (uint32_t)(( rand()/(double)RAND_MAX ) * ((double)_b-(double)_a) + (double)_a);
}
void etk::tool::resetRandom() {
srand(time(NULL));
void etk::random::reset() {
srand(time(0));
}
void etk::tool::randSeek(int32_t _val) {
void etk::random::resetSeed(int32_t _val) {
srand(_val);
}

View File

@ -10,10 +10,18 @@
namespace etk {
/**
* @brief Some useful tools
* @todo Remove all of this use std11 random
* @brief Some useful random elements
*/
namespace tool {
namespace random {
/**
* @brief Reset the random system with a random value (time).
*/
void reset();
/**
* @brief Reset the random system with The specify value.
* @param[in] _val Seek value for the pseudo random system.
*/
void resetSeed(int32_t _val);
/**
* @brief Get a random value in a specific range in float.
* @param[in] _a Lower value of the random.
@ -29,15 +37,61 @@ namespace etk {
*/
int32_t irand(int32_t _a=0x80000000, int32_t _b=0x7FFFFFFF);
uint32_t urand(uint32_t _a=0, uint32_t _b=0xFFFFFFFF);
template<typename ETK_RANDOM_TYPE_1, typename ETK_RANDOM_TYPE_2>
void shuffle(ETK_RANDOM_TYPE_1 _left, ETK_RANDOM_TYPE_2 _right) {
int32_t distance = etk::distance(_left, _right);
while (_left != _right) {
int64_t randValue = etk::random::urand(0, distance);
auto it = _left + randValue;
etk::swap(*_left, *it);
++_left;
}
}
}
/**
* @brief Some useful tools
* @todo Remove all of this use std11 random
*/
namespace tool {
/**
* @brief Get a random value in a specific range in float.
* @param[in] _a Lower value of the random.
* @param[in] _b Bigger value of the random.
* @return Random Value between [_a and _b]
* @note DEPRECATED
*/
inline double frand(double _a, double _b) {
return etk::random::frand(_a, _b);
}
/**
* @brief Get a random value in a specific range in integer.
* @param[in] _a Lower value of the random.
* @param[in] _b Bigger value of the random.
* @return Random Value between [_a and _b]
* @note DEPRECATED
*/
inline int32_t irand(int32_t _a=0x80000000, int32_t _b=0x7FFFFFFF) {
return etk::random::irand(_a, _b);
}
inline uint32_t urand(uint32_t _a=0, uint32_t _b=0xFFFFFFFF) {
return etk::random::urand(_a, _b);
}
/**
* @brief Reset the random system with a random value (time).
* @note DEPRECATED
*/
void resetRandom();
inline void resetRandom() {
etk::random::reset();
}
/**
* @brief Reset the random system with The specify value.
* @param[in] _val Seek value for the pseudo random system.
* @note DEPRECATED
*/
void randSeek(int32_t _val);
inline void randSeek(int32_t _val) {
etk::random::resetSeed(_val);
}
}
}

View File

@ -8,15 +8,6 @@
#include <etk/Vector.hpp>
#pragma once
// in header
template<typename T>
struct TypeParseTraits
{ static const char* name; };
// in c-file
#define REGISTER_PARSE_TYPE(X) \
template <> const char* TypeParseTraits<X>::name = #X
namespace etk {
template<typename ETK_TYPE>

View File

@ -154,4 +154,97 @@ namespace etk {
public etk::typeTrue {
};
#define DEFINE_METHOD_CHECKER(RETURN_TYPE, METHOD_NAME, PARAMETERS) \
template<typename ETK_TYPE> \
struct Is_ ## METHOD_NAME ## _MemberFunctionExists { \
private: \
typedef char True; \
typedef char (&False)[2]; \
template<typename U, RETURN_TYPE (U::*)PARAMETERS = &U::METHOD_NAME> \
struct Checker { \
typedef True Type; \
}; \
template<typename U> \
static typename Checker<U>::Type Tester(const U*); \
static False Tester(...); \
public: \
enum { value = (sizeof(Tester(static_cast<const ETK_TYPE*>(0))) == sizeof(True)) }; \
}
// Use example:
// Is_swap_MemberFunctionExists<T>::value
DEFINE_METHOD_CHECKER(void, swap, (ETK_TYPE&));
/*
#if 0
template<typename T>
struct hasEtkStreamExporter {
typedef char yes[1];
typedef char no[2];
template<typename U> static yes& test( U& );
template<typename U> static no& test(...);
static etk::Stream &s;
static T const &t;
static bool const value = sizeof( test( s << t ) ) == sizeof( yes ); // line 48
};
#else
namespace hasEtkStreamExporterImpl {
typedef char no;
typedef char yes[2];
struct AnyType {
template<typename ETK_TYPE> AnyType(const ETK_TYPE&);
};
no operator<<( etk::Stream&, const AnyType& );
yes& test( etk::Stream& );
no test( no );
template<typename ETK_TYPE>
struct hasEtkStreamExporter {
static etk::Stream& sss;
static const ETK_TYPE& ttt;
static bool const value = sizeof( test(sss << ttt) ) == sizeof( yes );
};
}
template<typename ETK_TYPE>
struct hasEtkStreamExporter:
etk::hasEtkStreamExporterImpl::hasEtkStreamExporter<ETK_TYPE> {
};
#endif
#if 1
template <typename T>
class hasMemberToString {
typedef char one;
typedef long two;
template <typename C> static one test( decltype(T::toString()) );
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
#else
namespace hasMemberToStringImpl {
typedef char no;
typedef char yes[2];
struct AnyType {
template<typename ETK_TYPE> AnyType(const ETK_TYPE&);
};
no operator<<( etk::Stream&, const AnyType& );
yes& test( etk::Stream& );
no test( no );
template<typename ETK_TYPE>
struct hasMemberToString {
static etk::Stream& sss;
static const ETK_TYPE& ttt;
static bool const value = sizeof( test(sss << ttt) ) == sizeof( yes );
};
}
template<typename ETK_TYPE>
struct hasMemberToString:
etk::hasMemberToStringImpl::hasMemberToString<ETK_TYPE> {
};
#endif
*/
}

View File

@ -49,6 +49,7 @@ def configure(target, my_module):
'etk/Stream.hpp',
'etk/Pair.hpp',
'etk/Map.hpp',
'etk/Set.hpp',
'etk/move.hpp',
'etk/typeTrait.hpp',
'etk/Function.hpp',

View File

@ -31,6 +31,7 @@ def configure(target, my_module):
'test/testFunction.cpp',
'test/testMapUnordered.cpp',
'test/testMap.cpp',
'test/testSet.cpp',
'test/testMatrix3x3.cpp',
'test/testRegExp.cpp',
'test/testTransform.cpp',

105
test/testSet.cpp Normal file
View File

@ -0,0 +1,105 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license MPL v2.0 (see license file)
*/
#include <etest/etest.hpp>
#include <etk/Set.hpp>
#include <test-debug/debug.hpp>
TEST(TestEtkSet, Creation) {
etk::Set<uint32_t> testData;
EXPECT_EQ(testData.size(), 0);
}
TEST(TestEtkSet, addGoodOrder) {
etk::Set<uint32_t> testData;
EXPECT_EQ(testData.size(), 0);
testData.add(2);
testData.add(9);
testData.add(1);
testData.add(6);
EXPECT_EQ(testData.size(), 4);
EXPECT_EQ(testData[0], 1);
EXPECT_EQ(testData[1], 2);
EXPECT_EQ(testData[2], 6);
EXPECT_EQ(testData[3], 9);
}
TEST(TestEtkSet, addMultiple) {
etk::Set<uint32_t> testData;
EXPECT_EQ(testData.size(), 0);
testData.add(2);
testData.add(9);
testData.add(9);
testData.add(2);
EXPECT_EQ(testData.size(), 2);
EXPECT_EQ(testData[0], 2);
EXPECT_EQ(testData[1], 9);
}
TEST(TestEtkSet, initializationList) {
etk::Set<int> testData = {7,2,3,3,1,99};
EXPECT_EQ(testData.size(), 5);
EXPECT_EQ(testData[0], 1);
EXPECT_EQ(testData[1], 2);
EXPECT_EQ(testData[2], 3);
EXPECT_EQ(testData[3], 7);
EXPECT_EQ(testData[4], 99);
}
TEST(TestEtkSet, find) {
etk::Set<int> testData = {1,2,3,66,74623};
EXPECT_EQ(testData.size(), 5);
auto it = testData.find(66);
EXPECT_EQ(it, testData.begin() + 3);
it = testData.find(99);
EXPECT_EQ(it, testData.end());
}
TEST(TestEtkSet, erase) {
etk::Set<int> testData = {1,3,4,2,0,7};
EXPECT_EQ(testData.size(), 6);
auto it = testData.erase(testData.begin() + 4);
EXPECT_EQ(testData.size(), 5);
EXPECT_EQ(testData[0], 0);
EXPECT_EQ(testData[1], 1);
EXPECT_EQ(testData[2], 2);
EXPECT_EQ(testData[3], 3);
EXPECT_EQ(testData[4], 7);
}
TEST(TestEtkSet, withStringClass) {
etk::Set<etk::String> testData;
EXPECT_EQ(testData.size(), 0);
testData.add("2");
testData.add("9");
testData.add("9");
testData.add("4");
EXPECT_EQ(testData.size(), 3);
EXPECT_EQ(testData[0], "2");
EXPECT_EQ(testData[1], "4");
EXPECT_EQ(testData[2], "9");
}
bool comp(const uint32_t& _left, const uint32_t& _right ) { return _left>_right; };
TEST(TestEtkSet, creationComparatorReverse) {
etk::Set<uint32_t> testData;
//auto comp = [](const uint32_t& _left, const uint32_t& _right ) { return _left>_right; };
testData.setComparator(&comp);
EXPECT_EQ(testData.size(), 0);
testData.add(2);
testData.add(9);
testData.add(1);
testData.add(6);
EXPECT_EQ(testData.size(), 4);
EXPECT_EQ(testData[0], 9);
EXPECT_EQ(testData[1], 6);
EXPECT_EQ(testData[2], 2);
EXPECT_EQ(testData[3], 1);
}

View File

@ -214,4 +214,48 @@ TEST(typeMove, move_1) {
EXPECT_EQ(contructCount, 1001);
}
static uint32_t swapMode = 0;
class TestSwap1 {
private:
uint32_t m_value;
public:
TestSwap1(uint32_t _value) {
m_value = _value;
swapMode += m_value;
}
~TestSwap1() {
swapMode += m_value;
}
};
class TestSwap2 {
private:
uint32_t m_value;
public:
TestSwap2(uint32_t _value) {
m_value = _value;
swapMode += m_value;
}
~TestSwap2() {
swapMode += m_value;
}
void swap(TestSwap2& _obj) {
swapMode += 1000000;
uint32_t tmp = m_value;
m_value = _obj.m_value;
_obj.m_value = tmp;
}
};
TEST(typeTrait, swap_1) {
bool ret = etk::Is_swap_MemberFunctionExists<TestSwap1>::value;
EXPECT_EQ(ret, false);
}
TEST(typeTrait, swap_2) {
bool ret = etk::Is_swap_MemberFunctionExists<TestSwap2>::value;
EXPECT_EQ(ret, true);
}

View File

@ -51,6 +51,53 @@ TEST(TestVector, pushBack) {
EXPECT_EQ(test[1], 4);
}
TEST(TestVector, pushFront) {
// Test contructor value
etk::Vector<float> test;
EXPECT_EQ(test.size(), 0);
test.pushBack(2);
EXPECT_EQ(test.size(), 1);
EXPECT_EQ(test[0], 2);
test.pushBack(4);
EXPECT_EQ(test.size(), 2);
EXPECT_EQ(test[0], 2);
EXPECT_EQ(test[1], 4);
test.pushFront(8);
EXPECT_EQ(test.size(), 3);
EXPECT_EQ(test[0], 8);
EXPECT_EQ(test[1], 2);
EXPECT_EQ(test[2], 4);
test.pushFront(55);
EXPECT_EQ(test.size(), 4);
EXPECT_EQ(test[0], 55);
EXPECT_EQ(test[1], 8);
EXPECT_EQ(test[2], 2);
EXPECT_EQ(test[3], 4);
}
TEST(TestVector, insert) {
// Test contructor value
etk::Vector<float> test;
EXPECT_EQ(test.size(), 0);
test.pushBack(2);
EXPECT_EQ(test.size(), 1);
EXPECT_EQ(test[0], 2);
test.pushBack(4);
EXPECT_EQ(test.size(), 2);
EXPECT_EQ(test[0], 2);
EXPECT_EQ(test[1], 4);
test.pushFront(8);
EXPECT_EQ(test.size(), 3);
EXPECT_EQ(test[0], 8);
EXPECT_EQ(test[1], 2);
EXPECT_EQ(test[2], 4);
test.pushFront(55);
EXPECT_EQ(test.size(), 4);
EXPECT_EQ(test[0], 55);
EXPECT_EQ(test[1], 8);
EXPECT_EQ(test[2], 2);
EXPECT_EQ(test[3], 4);
}
TEST(TestVector, back) {
// Test contructor value