[DEV] converge to a full implemented String classÃ

This commit is contained in:
Edouard DUPIN 2017-08-23 01:31:18 +02:00
parent 062f80baac
commit 427a603121
10 changed files with 813 additions and 608 deletions

View File

@ -0,0 +1,234 @@
#include <etk/String.hpp>
template <>
long double etk::String::to<long double>() {
long double ret = 0;
sscanf(c_str(), "%Lf", &ret);
return ret;
}
template <>
double etk::String::to<double>() {
double ret = 0;
sscanf(c_str(), "%lf", &ret);
return ret;
}
template <>
float etk::String::to<float>() {
float ret = 0;
sscanf(c_str(), "%f", &ret);
return ret;
}
template <>
int8_t etk::String::to<int8_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
int16_t etk::String::to<int16_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
int32_t etk::String::to<int32_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
int64_t etk::String::to<int64_t>() {
int64_t ret = 0;
#if ( defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__Windows) \
|| defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs))
sscanf(c_str(), "%lld", &ret);
#else
sscanf(c_str(), "%ld", &ret);
#endif
return ret;
}
template <>
uint8_t etk::String::to<uint8_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
uint16_t etk::String::to<uint16_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
uint32_t etk::String::to<uint32_t>() {
int ret = 0;
sscanf(c_str(), "%d", &ret);
return ret;
}
template <>
uint64_t etk::String::to<uint64_t>() {
uint64_t ret = 0;
#if ( defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__Windows) \
|| defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs))
sscanf(c_str(), "%llu", &ret);
#else
sscanf(c_str(), "%lu", &ret);
#endif
return ret;
}
std::ostream& etk::operator <<(std::ostream& _os, const etk::String& _obj) {
_os << _obj.c_str();
return _os;
}
std::ostream& etk::operator <<(std::ostream& _os, const etk::Vector<etk::String>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << " ~ ";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
void etk::sort(etk::Vector<etk::String *> &_list) {
etk::Vector<etk::String *> tmpList(_list);
_list.clear();
for(size_t iii=0; iii<tmpList.size(); iii++) {
size_t findPos = 0;
for(size_t jjj=0; jjj<_list.size(); jjj++) {
//TK_DEBUG("compare : \""<<*tmpList[iii] << "\" and \"" << *m_listDirectory[jjj] << "\"");
if (*tmpList[iii] > *_list[jjj]) {
findPos = jjj+1;
}
}
//TK_DEBUG("position="<<findPos);
_list.insert(_list.begin()+findPos, tmpList[iii]);
}
}
namespace etk {
template<> bool from_string<etk::String>(etk::String& _variableRet, const etk::String& _value) {
_variableRet = _value;
return true;
}
template<> bool from_string<int8_t>(int8_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_int8_t(_value);
return true;
}
template<> bool from_string<int16_t>(int16_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_int16_t(_value);
return true;
}
template<> bool from_string<int32_t>(int32_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_int32_t(_value);
return true;
}
template<> bool from_string<int64_t>(int64_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_int64_t(_value);
return true;
}
template<> bool from_string<uint8_t>(uint8_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_uint8_t(_value);
return true;
}
template<> bool from_string<uint16_t>(uint16_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_uint16_t(_value);
return true;
}
template<> bool from_string<uint32_t>(uint32_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_uint32_t(_value);
return true;
}
template<> bool from_string<uint64_t>(uint64_t& _variableRet, const etk::String& _value) {
_variableRet = string_to_uint64_t(_value);
return true;
}
template<> bool from_string<float>(float& _variableRet, const etk::String& _value) {
_variableRet = string_to_float(_value);
return true;
}
template<> bool from_string<double>(double& _variableRet, const etk::String& _value) {
_variableRet = string_to_double(_value);
return true;
}
template<> bool from_string<long double>(long double& _variableRet, const etk::String& _value) {
_variableRet = string_to_long_double(_value);
return true;
}
template<> bool from_string<bool>(bool& _variableRet, const etk::String& _value) {
_variableRet = string_to_bool(_value);
return true;
}
}
etk::String etk::toString(int _val) {
char tmpVal[256];
sprintf(tmpVal, "%d", _val);
return tmpVal;
}
etk::String etk::toString(long _val) {
char tmpVal[256];
sprintf(tmpVal, "%ld", _val);
return tmpVal;
}
etk::String etk::toString(long long _val) {
char tmpVal[256];
sprintf(tmpVal, "%lld", _val);
return tmpVal;
}
etk::String etk::toString(unsigned _val) {
char tmpVal[256];
sprintf(tmpVal, "%u", _val);
return tmpVal;
}
etk::String etk::toString(unsigned long _val) {
char tmpVal[256];
sprintf(tmpVal, "%lu", _val);
return tmpVal;
}
etk::String etk::toString(unsigned long long _val) {
char tmpVal[256];
sprintf(tmpVal, "%llu", _val);
return tmpVal;
}
etk::String etk::toString(float _val) {
char tmpVal[256];
sprintf(tmpVal, "%f", _val);
return tmpVal;
}
etk::String etk::toString(double _val) {
char tmpVal[256];
sprintf(tmpVal, "%f", _val);
return tmpVal;
}
etk::String etk::toString(long double _val) {
char tmpVal[256];
sprintf(tmpVal, "%Lf", _val);
return tmpVal;
}

View File

@ -7,8 +7,19 @@
#include <etk/types.hpp>
#include <etk/debug.hpp>
#include <etk/Vector.hpp>
namespace etk {
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;
}
/**
* @brief string class ...
*/
@ -105,18 +116,50 @@ namespace etk {
* @brief Get reference on the current Element
* @return the reference on the current Element
*/
ETK_VECTOR_TYPE & operator-> () const {
TK_CHECK_INOUT(m_current < m_string->size());
return &m_string->get(m_current);
char operator* () const {
TK_ASSERT(m_current < m_string->size(), "out of range");
return m_string->get(m_current);
}
/**
* @brief Get reference on the current Element
* @return the reference on the current Element
*/
ETK_VECTOR_TYPE & operator* () const {
TK_CHECK_INOUT(m_current < m_string->size());
char& operator* () {
TK_ASSERT(m_current < m_string->size(), "out of range");
return m_string->get(m_current);
}
/*****************************************************
* == operator
*****************************************************/
bool operator== (const Iterator& _obj) const {
// check if it was the same pointer
if( this == &_obj ) {
return true;
}
if (m_current != _obj.m_current) {
return false;
}
if (m_string != _obj.m_string) {
return false;
}
return true;
}
/*****************************************************
* != operator
*****************************************************/
bool operator!= (const Iterator& _obj) const {
// check if it was the same pointer
if( this == &_obj ) {
return false;
}
if (m_current != _obj.m_current) {
return true;
}
if (m_string != _obj.m_string) {
return true;
}
return false;
}
private:
Iterator(String* _obj, int32_t _pos):
m_current(_pos),
@ -126,23 +169,120 @@ namespace etk {
friend class String;
};
private:
std::string<char> m_data; //!< pointer on the current data (contain all time 1 element '\0')
etk::Vector<char> m_data; //!< pointer on the current data (contain all time 1 element '\0')
public:
static const size_t npos = size_t(-1);
/**
* @brief Create an empty string
* @param[in] _count Minimum request size of the Buffer (allocated at '\0')
*/
String(int32_t _count = 0):
String():
m_data() {
m_data.resize(_count, '\0');
m_data.resize(1, '\0');
}
/**
* @brief Re-copy constructor (copy all needed data)
* @brief Copy constructor (copy all data)
* @param[in] _obj String that might be copy
*/
String(const etk::String& _obj) {
m_data = _obj.m_data;
}
/**
* @brief Partial copy constructor (copy all needed data)
* @param[in] _obj String that might be copy (part of it)
* @param[in] _pos Start position to copy data
* @param[in] _size Number of element to copy in the string
*/
String(const etk::String& _obj, size_t _pos, size_t _size = etk::String::npos) {
if (_pos + _size >= _obj.size()) {
_size = etk::String::npos;
}
if (_size != etk::String::npos) {
resize(_size);
for (size_t iii=0; iii<_size; ++iii) {
m_data[iii] = _obj.m_data[_pos+iii];
}
return;
}
resize(_obj.size()-_pos);
for (size_t iii=0; iii<_obj.size()-_pos; ++iii) {
m_data[iii] = _obj.m_data[_pos+iii];
}
}
/**
* @brief Copy the null-terminated C string.
* @param[in] _obj C string that might be copy (end by '\0')
*/
String(const char* _obj) {
if (_obj == nullptr) {
resize(0);
return;
}
uint32_t size = strlen(_obj);
resize(size);
for (size_t iii=0; iii<size; ++iii) {
m_data[iii] = _obj[iii];
}
}
/**
* @brief Partial copy of the null-terminated C string.
* @param[in] _obj String that might be copyC string that might be copy (end by '\0')
* @param[in] _size Number of element to copy.
*/
String(const char* _obj, size_t _size) {
if ( _obj == nullptr
|| _size == 0) {
resize(0);
return;
}
uint32_t size = strlen(_obj);
if (_size < size) {
size = _size;
}
resize(size);
for (size_t iii=0; iii<size; ++iii) {
m_data[iii] = _obj[iii];
}
}
/**
* @brief Fills the string with _size consecutive copies of character _val.
* @param[in] _size Number of element in the string
* @param[in] _val Value to set in the string
*/
String(size_t _size, char _val) {
resize(_size);
for (size_t iii=0; iii<_size; ++iii) {
m_data[iii] = _val;
}
}
/**
* @brief Copy all element betewwen the 2 iterator of the new string.
* @param[in] _start Start iterator of adding value.
* @param[in] _stop Start iterator of adding value.
*/
String(Iterator _start, Iterator _stop) {
size_t size = etk::distance(_start, _stop);
resize(size);
Iterator it = begin();
while (_start != _stop) {
*it++ = *_start++;
}
}
/**
* @brief Move constructor
* @param[in] _obj String that might be move inside
*/
String(String&& _obj) noexcept {
m_data = std::move(_obj.m_data);
}
/**
* @brief Set constructor
* @param[in] _value Char element to set in the string
*/
String(char _value) {
resize(1);
m_data[0] = _value;
}
/**
* @brief Destructor of the current Class
*/
@ -164,13 +304,42 @@ namespace etk {
* @param[in] _obj String that might be copy
* @return reference on the current re-copy string
*/
String& operator=(const etk::String & _obj) {
String& operator=(const etk::String& _obj) {
if (this != &_obj) {
m_data = _obj.m_data;
}
// Return the current pointer
return *this;
}
/**
* @brief Re-copy operator
* @param[in] _obj C string terminated with '\0'
* @return reference on the current re-copy string
*/
String& operator=(const char* _obj) {
clear();
if (_obj == nullptr) {
return *this;
}
size_t numberElement = strlen(_obj);
resize(numberElement);
for (size_t iii=0; iii<numberElement; ++iii) {
m_data[iii] = _obj[iii];
}
// Return the current pointer
return *this;
}
/**
* @brief Re-copy operator
* @param[in] _value Char value to set in the string
* @return reference on the current re-copy string
*/
String& operator=(char _value) {
resize(1);
m_data[0] = _value;
// Return the current pointer
return *this;
}
/**
* @brief Add at the Last position of the String
@ -179,37 +348,45 @@ namespace etk {
String& operator+= (const etk::String& _obj) {
size_t numberElement = _obj.size();
size_t idElement = size();
resize(m_data.size()+_obj.size());
resize(size()+_obj.size());
for (size_t iii=0; iii<_obj.size(); ++iii) {
m_data[idElement+iii] = _obj[iii];
}
// Return the current pointer
return *this;
}
/**
* @brief Add at the Last position of the String
* @param[in] _obj C string terminated with '\0'
*/
String& operator+= (const char* _obj) {
if (_obj == nullptr) {
return *this;
}
size_t numberElement = strlen(_obj);
size_t idElement = size();
resize(size() + numberElement);
for (size_t iii=0; iii<numberElement; ++iii) {
m_data[idElement+iii] = _obj[iii];
}
// Return the current pointer
return *this;
}
/**
* @brief Add at the Last position of the String
* @param[in] _value Simple character to add.
*/
String& operator+= (char _value) {
pushBack(_value);
// Return the current pointer
return *this;
}
/**
* @brief Get the number of element in the string
* @return The number requested
*/
size_t size() const {
return m_size;
}
/**
* @brief Resize the string with a basic element
* @param[in] _newSize New size of the string
*/
void resize(size_t _newSize) {
size_t idElement = size();
resize(_newSize);
if (m_size != _newSize) {
TK_CRITICAL("error to resize string");
return;
}
if (_newSize > idElement) {
// initialize data ...
for(size_t iii=idElement; iii<_newSize; iii++) {
m_data[iii] = '\0';
}
}
return m_data.size() - 1; // remove '\0'
}
/**
* @brief Get a current element in the string
@ -217,7 +394,6 @@ namespace etk {
* @return Reference on the Element
*/
char& get(size_t _pos) {
// NOTE :Do not change log level, this generate error only in debug mode
return m_data[_pos];
}
/**
@ -226,7 +402,7 @@ namespace etk {
* @return An reference on the copy of selected element
*/
char& operator[] (size_t _pos) {
return get(_pos);
return m_data[_pos];
}
/**
* @brief Get an Element an a special position
@ -234,7 +410,6 @@ namespace etk {
* @return An reference on the selected element
*/
const char operator[] (size_t _pos) const {
// NOTE :Do not change log level, this generate error only in debug mode
return m_data[_pos];
}
/**
@ -257,9 +432,9 @@ namespace etk {
* @param[in] _item Element to add at the end of string
*/
void pushBack(const char _item) {
size_t idElement = m_size;
resize(m_size+1);
if (idElement < m_size) {
size_t idElement = size();
resize(size()+1);
if (idElement < size()) {
m_data[idElement] = _item;
} else {
TK_ERROR("Resize does not work correctly ... not added item");
@ -274,9 +449,9 @@ namespace etk {
if (_item == nullptr) {
return;
}
size_t idElement = m_size;
resize(m_size+_nbElement);
if (idElement > m_size) {
size_t idElement = size();
resize(size()+_nbElement);
if (idElement > size()) {
TK_ERROR("Resize does not work correctly ... not added item");
return;
}
@ -288,17 +463,15 @@ namespace etk {
* @brief Remove the last element of the string
*/
void popBack() {
if(m_size>0) {
resize(m_size-1);
if(size()>0) {
resize(size()-1);
}
}
/**
* @brief Remove all element in the current string
*/
void clear() {
if(m_size>0) {
resize(0);
}
resize(0);
}
/**
* @brief Insert N element in the String.
@ -307,15 +480,15 @@ namespace etk {
* @param[in] _nbElement Number of element to add in the String
*/
void insert(size_t _pos, const char* _item, size_t _nbElement) {
if (_pos>m_size) {
TK_WARNING(" can not insert Element at this position : " << _pos << " > " << m_size << " add it at the end ... ");
if (_pos>size()) {
TK_WARNING(" can not insert Element at this position : " << _pos << " > " << size() << " add it at the end ... ");
pushBack(_item, _nbElement);
return;
}
size_t idElement = m_size;
size_t idElement = size();
// Request resize of the current buffer
resize(m_size+_nbElement);
if (idElement>=m_size) {
resize(size()+_nbElement);
if (idElement>=size()) {
TK_ERROR("Resize does not work correctly ... not added item");
return;
}
@ -323,7 +496,7 @@ namespace etk {
size_t sizeToMove = (idElement - _pos);
if ( 0 < sizeToMove) {
for (size_t iii=1; iii<=sizeToMove; iii++) {
m_data[m_size-iii] = m_data[idElement-iii];
m_data[size()-iii] = m_data[idElement-iii];
}
}
// affectation of all input element
@ -344,15 +517,15 @@ namespace etk {
* @param[in] _pos Position to remove the data
* @param[in] _nbElement number of element to remove
*/
void eraseLen(size_t _pos, size_t _nbElement) {
if (_pos>m_size) {
TK_ERROR(" can not Erase Len Element at this position : " << _pos << " > " << m_size);
void erase(size_t _pos, size_t _nbElement=1) {
if (_pos>size()) {
TK_ERROR(" can not Erase Len Element at this position : " << _pos << " > " << size());
return;
}
if (_pos+_nbElement>m_size) {
_nbElement = m_size - _pos;
if (_pos+_nbElement>size()) {
_nbElement = size() - _pos;
}
size_t idElement = m_size;
size_t idElement = size();
// move current data
size_t sizeToMove = (idElement - (_pos+_nbElement));
if ( 0 < sizeToMove) {
@ -361,37 +534,23 @@ namespace etk {
}
}
// Request resize of the current buffer
resize(m_size-_nbElement);
}
/**
* @brief Remove one element
* @param[in] _pos Position to remove the data
*/
inline void erase(size_t _pos) {
eraseLen(_pos, 1);
}
/**
* @brief Remove one element
* @param[in] _pos Position to remove the data
*/
inline void remove(size_t _pos) {
eraseLen(_pos, 1);
resize(size() - _nbElement);
}
/**
* @brief Remove N elements
* @param[in] _pos Position to remove the data
* @param[in] _posEnd Last position number
*/
void erase(size_t _pos, size_t _posEnd) {
if (_pos>m_size) {
TK_ERROR(" can not Erase Element at this position : " << _pos << " > " << m_size);
void eraseRange(size_t _pos, size_t _posEnd) {
if (_pos>size()) {
TK_ERROR(" can not Erase Element at this position : " << _pos << " > " << size());
return;
}
if (_posEnd>m_size) {
_posEnd = m_size;
if (_posEnd > size()) {
_posEnd = size();
}
size_t nbElement = m_size - _pos;
size_t tmpSize = m_size;
size_t nbElement = size() - _pos;
size_t tmpSize = size();
// move current data
size_t sizeToMove = (tmpSize - (_pos+nbElement));
if ( 0 < sizeToMove) {
@ -400,7 +559,7 @@ namespace etk {
}
}
// Request resize of the current buffer
resize(m_size-nbElement);
resize(size()-nbElement);
}
/**
* @brief extract data between two point :
@ -408,7 +567,7 @@ namespace etk {
* @param[in] _posEnd End position to extract data
* @return the extracted string
*/
etk::String extract(size_t _posStart = 0, size_t _posEnd=0x7FFFFFFF) const {
etk::String extract(size_t _posStart = 0, size_t _posEnd=etk::String::npos) const {
etk::String out;
if (_posStart >= size() ) {
return out;
@ -432,7 +591,7 @@ namespace etk {
* @return The Iterator
*/
Iterator position(size_t _pos) {
return iterator(this, _pos);
return Iterator(this, _pos);
}
/**
* @brief Get an Iterator on the start position of the String
@ -448,22 +607,18 @@ namespace etk {
Iterator end() {
return position( size()-1 );
}
private:
/**
* @brief Change the current size of the string
* @param[in] _newSize New requested size of element in the string
* @param[in] _value Value to set at the new element
*/
void resize(size_t _newSize) {
void resize(size_t _newSize, char _value = '\0') {
size_t oldSize = m_data.size();
m_data.resize(_newSize + 1);
m_data[m_data.size()-1] = _value;
m_data.resize(_newSize + 1, _value);
// in all case ==> we have the last element that is '\0'
m_data[_newSize] = '\0';
// Clear all end data to prevent errors
for (size_t iii=oldSize; iii<_newSize; ++iii) {
m_data[iii] = '\0';
}
}
public :
/*****************************************************
* == operator
*****************************************************/
@ -473,7 +628,7 @@ namespace etk {
return true;
}
// first step : check the size ...
if (m_size != _obj.m_size) {
if (m_data.size() != _obj.m_data.size()) {
return false;
}
for (size_t iii=0; iii<m_data.size(); ++iii) {
@ -492,7 +647,7 @@ namespace etk {
return false;
}
// first step : check the size ...
if (m_size != _obj.m_size) {
if (m_data.size() != _obj.m_data.size()) {
return true;
}
for (size_t iii=0; iii<m_data.size(); ++iii) {
@ -502,5 +657,86 @@ namespace etk {
}
return false;
}
/**
* @brief Template that permit to convert string in everythings you want
* @param[in] ETK_STRING_TYPE Template type of the convertion output
*/
template <class ETK_STRING_TYPE>
ETK_STRING_TYPE to();
};
String operator+ (const String& _left, const String& _right) {
String tmp = _left;
tmp += _right;
return tmp;
}
String operator+ (const String& _left, const char* _right) {
String tmp = _left;
tmp += _right;
return tmp;
}
String operator+ (const char* _left, const String& _right) {
String tmp = _left;
tmp += _right;
return tmp;
}
String operator+ (const String& _left, char _right) {
String tmp = _left;
tmp.pushBack(_right);
return tmp;
}
String operator+ (char _left, const String& _right) {
String tmp = _left;
tmp += _right;
return tmp;
}
/**
* @brief Template to declare conversion from anything in etk::String
* @param[in] _variable Variable to convert
* @return String of the value
*/
template <class TYPE>
etk::String toString(const TYPE& _variable);
/**
* @brief Template to declare conversion from std::vector<anything> in etk::String
* @param[in] _list Variable to convert
* @return String of the value: {...,...,...}
*/
template <class TYPE>
etk::String toString(const std::vector<TYPE>& _list) {
etk::String out = "{";
for (size_t iii=0; iii<_list.size(); ++iii) {
if (iii!=0) {
out += ";";
}
out+= etk::toString(_list[iii]);
}
out += "}";
return out;
}
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const etk::String& _obj);
/**
* @brief Template to declare conversion from string to anything
* @param[out] _variableRet Output value
* @param[in] _value input property
* @return true if the can be converted.
*/
template <class TYPE>
bool from_string(TYPE& _variableRet, const etk::String& _value);
etk::String tolower(etk::String _obj);
etk::String toupper(etk::String _obj);
bool compare_no_case(const etk::String& _obj, const etk::String& _val);
bool end_with(const etk::String& _obj, const etk::String& _val, bool _caseSensitive = true);
bool start_with(const etk::String& _obj, const etk::String& _val, bool _caseSensitive = true);
etk::String replace(const etk::String& _obj, char _val, char _replace);
etk::String replace(const etk::String& _obj, const etk::String& _val, const etk::String& _replace);
etk::String extract_line(const etk::String& _obj, int32_t _pos);
etk::Vector<etk::String> split(const etk::String& _input, char _val);
etk::Vector<etk::String> split(const etk::String& _input, etk::String _val);
void sort(etk::Vector<etk::String *>& _list);
}

View File

@ -6,6 +6,7 @@
#pragma once
#include <etk/types.hpp>
#include <etk/stdTools.hpp>
#include <etk/debug.hpp>
namespace etk {
@ -605,7 +606,7 @@ namespace etk {
return;
}
// copy data in the new pool
size_t nbElements = etk_min(requestSize, m_allocated);
size_t nbElements = etk::min(requestSize, m_allocated);
for(size_t iii=0; iii<nbElements; iii++) {
m_dataTmp[iii] = std::move(m_data[iii]);
}
@ -668,4 +669,16 @@ namespace etk {
return false;
}
};
template<class ETK_VECTOR_TYPE>
std::ostream& operator <<(std::ostream& _os, const etk::Vector<ETK_VECTOR_TYPE>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
}

View File

@ -858,94 +858,7 @@ std::vector<std::string> etk::split(const std::string& _input, std::string _val)
return list;
}
long double etk::string_to_long_double(const std::string& _str) {
long double ret = 0;
sscanf(_str.c_str(), "%Lf", &ret);
return ret;
}
double etk::string_to_double(const std::string& _str) {
double ret = 0;
sscanf(_str.c_str(), "%lf", &ret);
return ret;
}
float etk::string_to_float(const std::string& _str) {
float ret = 0;
sscanf(_str.c_str(), "%f", &ret);
return ret;
}
int8_t etk::string_to_int8_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
int16_t etk::string_to_int16_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
int32_t etk::string_to_int32_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
int64_t etk::string_to_int64_t(const std::string& _str, int _base) {
int64_t ret = 0;
#if ( defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__Windows) \
|| defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs))
sscanf(_str.c_str(), "%lld", &ret);
#else
sscanf(_str.c_str(), "%ld", &ret);
#endif
return ret;
}
uint8_t etk::string_to_uint8_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
uint16_t etk::string_to_uint16_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
uint32_t etk::string_to_uint32_t(const std::string& _str, int _base) {
int ret = 0;
sscanf(_str.c_str(), "%d", &ret);
return ret;
}
uint64_t etk::string_to_uint64_t(const std::string& _str, int _base) {
uint64_t ret = 0;
#if ( defined(__TARGET_OS__Android) \
|| defined(__TARGET_OS__Windows) \
|| defined(__TARGET_OS__MacOs) \
|| defined(__TARGET_OS__IOs))
sscanf(_str.c_str(), "%llu", &ret);
#else
sscanf(_str.c_str(), "%lu", &ret);
#endif
return ret;
}
void etk::sort(std::vector<std::string *> &_list) {
std::vector<std::string *> tmpList(_list);
_list.clear();
for(size_t iii=0; iii<tmpList.size(); iii++) {
size_t findPos = 0;
for(size_t jjj=0; jjj<_list.size(); jjj++) {
//TK_DEBUG("compare : \""<<*tmpList[iii] << "\" and \"" << *m_listDirectory[jjj] << "\"");
if (*tmpList[iii] > *_list[jjj]) {
findPos = jjj+1;
}
}
//TK_DEBUG("position="<<findPos);
_list.insert(_list.begin()+findPos, tmpList[iii]);
}
}
#if __CPP_VERSION__ >= 2011
void etk::sort(std::vector<std::u32string *> &_list) {
std::vector<std::u32string *> tmpList(_list);
@ -970,60 +883,6 @@ namespace etk {
_variableRet = etk::to_u32string(_value);
return true;
}
#endif
template<> bool from_string<std::string>(std::string& _variableRet, const std::string& _value) {
_variableRet = _value;
return true;
}
template<> bool from_string<int8_t>(int8_t& _variableRet, const std::string& _value) {
_variableRet = string_to_int8_t(_value);
return true;
}
template<> bool from_string<int16_t>(int16_t& _variableRet, const std::string& _value) {
_variableRet = string_to_int16_t(_value);
return true;
}
template<> bool from_string<int32_t>(int32_t& _variableRet, const std::string& _value) {
_variableRet = string_to_int32_t(_value);
return true;
}
template<> bool from_string<int64_t>(int64_t& _variableRet, const std::string& _value) {
_variableRet = string_to_int64_t(_value);
return true;
}
template<> bool from_string<uint8_t>(uint8_t& _variableRet, const std::string& _value) {
_variableRet = string_to_uint8_t(_value);
return true;
}
template<> bool from_string<uint16_t>(uint16_t& _variableRet, const std::string& _value) {
_variableRet = string_to_uint16_t(_value);
return true;
}
template<> bool from_string<uint32_t>(uint32_t& _variableRet, const std::string& _value) {
_variableRet = string_to_uint32_t(_value);
return true;
}
template<> bool from_string<uint64_t>(uint64_t& _variableRet, const std::string& _value) {
_variableRet = string_to_uint64_t(_value);
return true;
}
template<> bool from_string<float>(float& _variableRet, const std::string& _value) {
_variableRet = string_to_float(_value);
return true;
}
template<> bool from_string<double>(double& _variableRet, const std::string& _value) {
_variableRet = string_to_double(_value);
return true;
}
template<> bool from_string<long double>(long double& _variableRet, const std::string& _value) {
_variableRet = string_to_long_double(_value);
return true;
}
template<> bool from_string<bool>(bool& _variableRet, const std::string& _value) {
_variableRet = string_to_bool(_value);
return true;
}
#if __CPP_VERSION__ >= 2011
template<> bool from_string<int8_t>(int8_t& _variableRet, const std::u32string& _value) {
_variableRet = string_to_int8_t(_value);
return true;
@ -1076,22 +935,6 @@ namespace etk {
};
std::ostream& std::operator <<(std::ostream& _os, const std::string& _obj) {
_os << _obj.c_str();
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<std::string>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << " ~ ";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
#if __CPP_VERSION__ >= 2011
std::ostream& std::operator <<(std::ostream& _os, const std::u32string& _obj) {
_os << etk::to_string(_obj).c_str();
@ -1111,172 +954,7 @@ std::ostream& std::operator <<(std::ostream& _os, const std::vector<std::string>
}
#endif
std::ostream& std::operator <<(std::ostream& _os, const std::vector<float>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<double>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<int64_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<uint64_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<int32_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<uint32_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<int16_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<uint16_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<int8_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
std::ostream& std::operator <<(std::ostream& _os, const std::vector<uint8_t>& _obj) {
_os << "{";
for (size_t iii=0; iii< _obj.size(); iii++) {
if (iii>0) {
_os << ";";
}
_os << _obj[iii];
}
_os << "}";
return _os;
}
#if (defined(__TARGET_OS__Android))
std::string std::to_string(int _val) {
char tmpVal[256];
sprintf(tmpVal, "%d", _val);
return tmpVal;
}
std::string std::to_string(long _val) {
char tmpVal[256];
sprintf(tmpVal, "%ld", _val);
return tmpVal;
}
std::string std::to_string(long long _val) {
char tmpVal[256];
sprintf(tmpVal, "%lld", _val);
return tmpVal;
}
std::string std::to_string(unsigned _val) {
char tmpVal[256];
sprintf(tmpVal, "%u", _val);
return tmpVal;
}
std::string std::to_string(unsigned long _val) {
char tmpVal[256];
sprintf(tmpVal, "%lu", _val);
return tmpVal;
}
std::string std::to_string(unsigned long long _val) {
char tmpVal[256];
sprintf(tmpVal, "%llu", _val);
return tmpVal;
}
std::string std::to_string(float _val) {
char tmpVal[256];
sprintf(tmpVal, "%f", _val);
return tmpVal;
}
std::string std::to_string(double _val) {
char tmpVal[256];
sprintf(tmpVal, "%f", _val);
return tmpVal;
}
std::string std::to_string(long double _val) {
char tmpVal[256];
sprintf(tmpVal, "%Lf", _val);
return tmpVal;
}
double std::stod(const std::string& _str, size_t* _id) {
double ret = 0;

View File

@ -433,209 +433,34 @@ namespace utf8 {
};
};
namespace std {
#if (defined(__TARGET_OS__MacOs) || defined(__TARGET_OS__Windows))
using u32string = std::basic_string<char32_t>;
#endif
#if (defined(__TARGET_OS__Android))
//! @not_in_doc
std::string to_string(int _val);
//! @not_in_doc
std::string to_string(long _val);
//! @not_in_doc
std::string to_string(long long _val);
//! @not_in_doc
std::string to_string(unsigned _val);
//! @not_in_doc
std::string to_string(unsigned long _val);
//! @not_in_doc
std::string to_string(unsigned long long _val);
//! @not_in_doc
std::string to_string(float _val);
//! @not_in_doc
std::string to_string(double _val);
//! @not_in_doc
std::string to_string(long double _val);
//! @not_in_doc
double stod(const std::string& _str, size_t* _id = 0);
//! @not_in_doc
float stof(const std::string& _str, size_t* _id = 0);
//! @not_in_doc
int stoi(const std::string& _str, size_t* _id = 0, int _base = 10);
//! @not_in_doc
long stol(const std::string& _str, size_t* _id = 0, int _base = 10);
//! @not_in_doc
long double stold(const std::string& _str, size_t* _id = 0);
//! @not_in_doc
long long stoll(const std::string& _str, size_t* _id = 0, int _base = 10);
//! @not_in_doc
unsigned long stoul(const std::string& _str, size_t* _id = 0, int _base = 10);
//! @not_in_doc
unsigned long long stoull(const std::string& _str, size_t* _id = 0, int _base = 10);
#endif
};
namespace etk {
// these declaration is to prevent some under template declaration of unknown type
/**
* @brief Template to declare conversion from anything in std::string
* @param[in] _variable Variable to convert
* @return String of the value
*/
template <class TYPE>
std::string to_string(const TYPE& _variable);
/**
* @brief Template to declare conversion from std::vector<anything> in std::string
* @param[in] _list Variable to convert
* @return String of the value: {...,...,...}
*/
template <class TYPE>
std::string to_string(const std::vector<TYPE>& _list) {
std::string out = "{";
for (size_t iii=0; iii<_list.size(); ++iii) {
if (iii!=0) {
out += ";";
}
out+= etk::to_string(_list[iii]);
}
out += "}";
return out;
}
#if __CPP_VERSION__ >= 2011
template <class TYPE>
std::u32string to_u32string(const TYPE& _variable);
#endif
// these declaration is to prevent some under template declaration of unknown type
/**
* @brief Template to declare conversion from string to anything
* @param[out] _variableRet Output value
* @param[in] _value input property
* @return true if the can be converted.
*/
template <class TYPE>
bool from_string(TYPE& _variableRet, const std::string& _value);
#if __CPP_VERSION__ >= 2011
template <class TYPE>
bool from_string(TYPE& _variableRet, const std::u32string& _value);
#endif
// TODO : Change this in :
// TODO : template <typename TYPE> TYPE string_to<TYPE>(const std::u32string& _value); ==> check exceptions ...
//! @not_in_doc
long double string_to_long_double(const std::string& _str);
#if __CPP_VERSION__ >= 2011
long double string_to_long_double(const std::u32string& _str);
#endif
//! @not_in_doc
double string_to_double(const std::string& _str);
#if __CPP_VERSION__ >= 2011
double string_to_double(const std::u32string& _str);
#endif
//! @not_in_doc
float string_to_float(const std::string& _str);
#if __CPP_VERSION__ >= 2011
float string_to_float(const std::u32string& _str);
#endif
//! @not_in_doc
int8_t string_to_int8_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
int8_t string_to_int8_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
int16_t string_to_int16_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
int16_t string_to_int16_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
int32_t string_to_int32_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
int32_t string_to_int32_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
int64_t string_to_int64_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
int64_t string_to_int64_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
uint8_t string_to_uint8_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
uint8_t string_to_uint8_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
uint16_t string_to_uint16_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
uint16_t string_to_uint16_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
uint32_t string_to_uint32_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
uint32_t string_to_uint32_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
uint64_t string_to_uint64_t(const std::string& _str, int _base = 10);
#if __CPP_VERSION__ >= 2011
uint64_t string_to_uint64_t(const std::u32string& _str, int _base = 10);
#endif
//! @not_in_doc
bool string_to_bool(const std::string& _str);
#if __CPP_VERSION__ >= 2011
bool string_to_bool(const std::u32string& _str);
#endif
//! @not_in_doc
std::string tolower(std::string _obj);
#if __CPP_VERSION__ >= 2011
//! @previous
std::u32string tolower(std::u32string _obj);
#endif
//! @not_in_doc
std::string toupper(std::string _obj);
#if __CPP_VERSION__ >= 2011
//! @previous
std::u32string toupper(std::u32string _obj);
#endif
//! @not_in_doc
bool compare_no_case(const std::string& _obj, const std::string& _val);
#if __CPP_VERSION__ >= 2011
//! @previous
bool compare_no_case(const std::u32string& _obj, const std::u32string& _val);
#endif
//! @not_in_doc
bool end_with(const std::string& _obj, const std::string& _val, bool _caseSensitive = true);
#if __CPP_VERSION__ >= 2011
//! @previous
bool end_with(const std::u32string& _obj, const std::u32string& _val, bool _caseSensitive = true);
#endif
//! @not_in_doc
bool start_with(const std::string& _obj, const std::string& _val, bool _caseSensitive = true);
#if __CPP_VERSION__ >= 2011
//! @previous
bool start_with(const std::u32string& _obj, const std::u32string& _val, bool _caseSensitive = true);
#endif
//! @not_in_doc
std::string replace(const std::string& _obj, char _val, char _replace);
#if __CPP_VERSION__ >= 2011
//! @previous
std::u32string replace(const std::u32string& _obj, char32_t _val, char32_t _replace);
#endif
//! @not_in_doc
std::string replace(const std::string& _obj, const std::string& _val, const std::string& _replace);
//! @not_in_doc
std::string extract_line(const std::string& _obj, int32_t _pos);
#if __CPP_VERSION__ >= 2011
//! @previous
std::u32string extract_line(const std::u32string& _obj, int32_t _pos);
#endif
//! @not_in_doc
std::vector<std::string> split(const std::string& _input, char _val);
#if __CPP_VERSION__ >= 2011
//! @previous
std::vector<std::u32string> split(const std::u32string& _input, char32_t _val);
#endif
//! @not_in_doc
std::vector<std::string> split(const std::string& _input, std::string _val);
//! @not_in_doc
void sort(std::vector<std::string *>& _list);
#if __CPP_VERSION__ >= 2011
//! @previous
void sort(std::vector<std::u32string *>& _list);
#endif
//! @not_in_doc
@ -650,20 +475,13 @@ namespace etk {
}
};
namespace std {
/**
* @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 std::min(std::max(_min,_val),_max);
}
};
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
@ -677,10 +495,6 @@ namespace etk {
};
namespace std {
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const std::string& _obj);
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const std::vector<std::string>& _obj);
#if __CPP_VERSION__ >= 2011
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const std::u32string& _obj);

View File

@ -39,6 +39,7 @@ def configure(target, my_module):
'test/testQuaternion.cpp',
'test/testStdShared.cpp',
'test/testVector2_f.cpp',
'test/testString.cpp',
])
my_module.add_depend([
'etk',

View File

@ -60,6 +60,8 @@ def configure(target, my_module):
'etk/RegEx.hpp',
'etk/Buffer.hpp',
'etk/Hash.hpp',
'etk/String.hpp',
'etk/Vector.hpp',
'etk/math/Matrix2x2.hpp',
'etk/math/Matrix2x3.hpp',
'etk/math/Matrix3x3.hpp',

0
test/testMap.cpp Normal file
View File

227
test/testString.cpp Normal file
View File

@ -0,0 +1,227 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/String.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk:String"
TEST(TestString, constructor) {
// Test contructor value
etk::String test0;
EXPECT_FLOAT_EQ(test0.size(), 0);
EXPECT_FLOAT_EQ(test0.c_str()[0], '\0');
etk::String test1("hello");
EXPECT_FLOAT_EQ(test1.size(), 5);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'e');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'l');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'l');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'o');
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
etk::String test2(test1);
EXPECT_FLOAT_EQ(test2.size(), 5);
EXPECT_FLOAT_EQ(test2.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test2.c_str()[1], 'e');
EXPECT_FLOAT_EQ(test2.c_str()[2], 'l');
EXPECT_FLOAT_EQ(test2.c_str()[3], 'l');
EXPECT_FLOAT_EQ(test2.c_str()[4], 'o');
EXPECT_FLOAT_EQ(test2.c_str()[5], '\0');
etk::String test3(test1, 2);
EXPECT_FLOAT_EQ(test3.size(), 3);
EXPECT_FLOAT_EQ(test3.c_str()[0], 'l');
EXPECT_FLOAT_EQ(test3.c_str()[1], 'l');
EXPECT_FLOAT_EQ(test3.c_str()[2], 'o');
EXPECT_FLOAT_EQ(test3.c_str()[3], '\0');
etk::String test4(test1, 1, 3);
EXPECT_FLOAT_EQ(test4.size(), 3);
EXPECT_FLOAT_EQ(test4.c_str()[0], 'e');
EXPECT_FLOAT_EQ(test4.c_str()[1], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[3], '\0');
}
TEST(TestString, equality) {
etk::String test2("hello");
etk::String test4("maeau");
test4 = 'c';
EXPECT_FLOAT_EQ(test4.size(), 1);
EXPECT_FLOAT_EQ(test4.c_str()[0], 'c');
EXPECT_FLOAT_EQ(test4.c_str()[1], '\0');
test4 = "prout";
EXPECT_FLOAT_EQ(test4.size(), 5);
EXPECT_FLOAT_EQ(test4.c_str()[0], 'p');
EXPECT_FLOAT_EQ(test4.c_str()[1], 'r');
EXPECT_FLOAT_EQ(test4.c_str()[2], 'o');
EXPECT_FLOAT_EQ(test4.c_str()[3], 'u');
EXPECT_FLOAT_EQ(test4.c_str()[4], 't');
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
test4 = test2;
EXPECT_FLOAT_EQ(test4.size(), 5);
EXPECT_FLOAT_EQ(test4.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test4.c_str()[1], 'e');
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[3], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[4], 'o');
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
}
TEST(TestString, swap) {
etk::String test2("hello");
etk::String test4 = "plo";
test4.swap(test2);
EXPECT_FLOAT_EQ(test4.size(), 5);
EXPECT_FLOAT_EQ(test4.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test4.c_str()[1], 'e');
EXPECT_FLOAT_EQ(test4.c_str()[2], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[3], 'l');
EXPECT_FLOAT_EQ(test4.c_str()[4], 'o');
EXPECT_FLOAT_EQ(test4.c_str()[5], '\0');
EXPECT_FLOAT_EQ(test2.size(), 3);
EXPECT_FLOAT_EQ(test2.c_str()[0], 'p');
EXPECT_FLOAT_EQ(test2.c_str()[1], 'l');
EXPECT_FLOAT_EQ(test2.c_str()[2], 'o');
EXPECT_FLOAT_EQ(test2.c_str()[3], '\0');
}
TEST(TestString, equalityComparison) {
etk::String test1("hello");
etk::String test2("hello2");
EXPECT_FLOAT_EQ(test1 == test2, false);
EXPECT_FLOAT_EQ(test1 != test2, true);
test1 = "hello2";
EXPECT_FLOAT_EQ(test1 != test2, false);
EXPECT_FLOAT_EQ(test1 == test2, true);
}
TEST(TestString, resize) {
etk::String test1("hello");
test1.resize(0);
EXPECT_FLOAT_EQ(test1.size(), 0);
test1.resize(3);
EXPECT_FLOAT_EQ(test1.size(), 3);
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[3], '\0');
test1.resize(2, 'g');
EXPECT_FLOAT_EQ(test1.size(), 2);
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
test1.resize(5, 'g');
EXPECT_FLOAT_EQ(test1.size(), 5);
EXPECT_FLOAT_EQ(test1.c_str()[0], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
}
TEST(TestString, add) {
etk::String test1("h");
test1 += 'r';
EXPECT_FLOAT_EQ(test1.size(), 2);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
test1 += "kg";
EXPECT_FLOAT_EQ(test1.size(), 4);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'k');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[4], '\0');
test1 += etk::String("Ui");
EXPECT_FLOAT_EQ(test1.size(), 6);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'k');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'U');
EXPECT_FLOAT_EQ(test1.c_str()[5], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[6], '\0');
}
TEST(TestString, insert) {
etk::String test1("hrkgUi");
test1.insert(0, 'F');
EXPECT_FLOAT_EQ(test1.size(), 7);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'k');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[5], 'U');
EXPECT_FLOAT_EQ(test1.c_str()[6], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[7], '\0');
test1.insert(7, 'Z');
EXPECT_FLOAT_EQ(test1.size(), 8);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'k');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[5], 'U');
EXPECT_FLOAT_EQ(test1.c_str()[6], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[7], 'Z');
EXPECT_FLOAT_EQ(test1.c_str()[8], '\0');
test1.insert(2, 'H');
EXPECT_FLOAT_EQ(test1.size(), 9);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'F');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'H');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'r');
EXPECT_FLOAT_EQ(test1.c_str()[4], 'k');
EXPECT_FLOAT_EQ(test1.c_str()[5], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[6], 'U');
EXPECT_FLOAT_EQ(test1.c_str()[7], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[8], 'Z');
EXPECT_FLOAT_EQ(test1.c_str()[9], '\0');
}
TEST(TestString, eraseLen) {
etk::String test1("hrkgUi");
test1.erase(0, 3);
EXPECT_FLOAT_EQ(test1.size(), 3);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'U');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[3], '\0');
test1.erase(1, 1);
EXPECT_FLOAT_EQ(test1.size(), 2);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'i');
EXPECT_FLOAT_EQ(test1.c_str()[2], '\0');
test1.erase(1, 100);
EXPECT_FLOAT_EQ(test1.size(), 1);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'g');
EXPECT_FLOAT_EQ(test1.c_str()[1], '\0');
}
TEST(TestString, additionExtern) {
etk::String test1 = "aa" + etk::String("he") + 't';
EXPECT_FLOAT_EQ(test1.size(), 5);
EXPECT_FLOAT_EQ(test1.c_str()[0], 'a');
EXPECT_FLOAT_EQ(test1.c_str()[1], 'a');
EXPECT_FLOAT_EQ(test1.c_str()[2], 'h');
EXPECT_FLOAT_EQ(test1.c_str()[3], 'e');
EXPECT_FLOAT_EQ(test1.c_str()[4], 't');
EXPECT_FLOAT_EQ(test1.c_str()[5], '\0');
}

0
test/testVector.cpp Normal file
View File