Loading...
Searching...
No Matches
string.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2016 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_STRING_INCLUDED
#define ETL_STRING_INCLUDED
#include "platform.h"
#include "basic_string.h"
#include "hash.h"
#include "initializer_list.h"
#include "string_view.h"
#include <ctype.h>
#include "private/minmax_push.h"
namespace etl
{
#if ETL_USING_CPP11
inline namespace literals
{
inline namespace string_literals
{
inline constexpr etl::string_view operator""_sv(const char* str, size_t length) ETL_NOEXCEPT
{
return etl::string_view{str, length};
}
} // namespace string_literals
} // namespace literals
#endif
typedef etl::ibasic_string<char> istring;
//***************************************************************************
//***************************************************************************
template <size_t MAX_SIZE_>
class string : public istring
{
public:
typedef istring base_type;
typedef istring interface_type;
typedef istring::value_type value_type;
typedef istring::size_type size_type;
static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
//*************************************************************************
string()
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
string(const etl::string<MAX_SIZE_>& other)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(other);
}
//*************************************************************************
//*************************************************************************
string(const etl::istring& other)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(other);
}
//*************************************************************************
//*************************************************************************
string(const etl::istring& other, size_t position, size_t length = npos)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
this->assign(other, position, length);
}
//*************************************************************************
//*************************************************************************
ETL_EXPLICIT_STRING_FROM_CHAR string(const value_type* text)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(text);
}
//*************************************************************************
//*************************************************************************
string(const value_type* text, size_t count)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(text, text + count);
}
//*************************************************************************
//*************************************************************************
string(size_type count, value_type c)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->initialise();
this->resize(count, c);
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
string(std::initializer_list<value_type> init)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
explicit string(const etl::string_view& view)
: istring(reinterpret_cast<value_type*>(&buffer), MAX_SIZE)
{
this->assign(view.begin(), view.end());
}
//*************************************************************************
//*************************************************************************
etl::string<MAX_SIZE_> substr(size_type position = 0, size_type length_ = npos) const
{
etl::string<MAX_SIZE_> new_string;
if (position != this->size())
{
ETL_ASSERT(position < this->size(), ETL_ERROR(string_out_of_bounds));
length_ = etl::min(length_, this->size() - position);
new_string.assign(buffer + position, buffer + position + length_);
}
return new_string;
}
//*************************************************************************
//*************************************************************************
string& operator=(const string& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
//*************************************************************************
string& operator=(const istring& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
//*************************************************************************
string& operator=(const value_type* text)
{
this->assign(text);
return *this;
}
//*************************************************************************
//*************************************************************************
string& operator=(const etl::string_view& view)
{
this->assign(view);
return *this;
}
//*************************************************************************
//*************************************************************************
#if ETL_HAS_ISTRING_REPAIR
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::istring::repair_buffer(buffer);
}
private:
value_type buffer[MAX_SIZE + 1];
};
template <size_t MAX_SIZE_>
ETL_CONSTANT typename string<MAX_SIZE_>::size_type string<MAX_SIZE_>::MAX_SIZE;
//***************************************************************************
//***************************************************************************
class string_ext : public istring
{
public:
typedef istring base_type;
typedef istring interface_type;
typedef istring::value_type value_type;
typedef istring::size_type size_type;
//*************************************************************************
//*************************************************************************
string_ext(value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
template <size_t Size>
string_ext(value_type (&buffer)[Size])
: istring(buffer, Size - 1U)
{
this->initialise();
}
//*************************************************************************
//*************************************************************************
string_ext(const etl::string_ext& other, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(other.data()))
{
this->current_size = other.size();
}
else
{
this->assign(other);
}
}
//*************************************************************************
//*************************************************************************
string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(other.data()))
{
this->current_size = other.size();
}
else
{
this->assign(other);
}
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
string_ext(const etl::istring& other, value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(other.data()))
{
this->current_size = other.size();
}
else
{
this->assign(other);
}
}
//*************************************************************************
//*************************************************************************
string_ext(const etl::istring& other, value_type* buffer, size_type buffer_size, size_type position, size_type length = npos)
: istring(buffer, buffer_size - 1U)
{
ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
if (this->is_within_buffer(other.data()))
{
this->current_size = other.size();
}
else
{
this->assign(other, position, length);
}
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
string_ext(const etl::istring& other, value_type (&buffer)[BufferSize], size_type position, size_type length = npos)
: istring(buffer, BufferSize - 1U)
{
ETL_ASSERT(position < other.size(), ETL_ERROR(string_out_of_bounds));
if (this->is_within_buffer(other.data()))
{
this->current_size = other.size();
}
else
{
this->assign(other, position, length);
}
}
//*************************************************************************
//*************************************************************************
template <typename TPointer>
string_ext(TPointer text, value_type* buffer, size_type buffer_size,
typename etl::enable_if<etl::is_same<const value_type*, TPointer>::value, int>::type* = ETL_NULLPTR)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(text))
{
this->current_size = etl::strlen(buffer);
}
else
{
this->assign(text);
}
}
//*************************************************************************
//*************************************************************************
template <typename TPointer, size_t BufferSize>
string_ext(TPointer text, value_type (&buffer)[BufferSize],
typename etl::enable_if<etl::is_same<const value_type*, TPointer>::value, int>::type* = ETL_NULLPTR)
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(text))
{
this->current_size = etl::strlen(buffer);
}
else
{
this->assign(text);
}
}
//*************************************************************************
//*************************************************************************
template <size_t Size>
string_ext(const value_type (&literal)[Size], value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(literal))
{
this->current_size = etl::strlen(literal);
}
else
{
this->assign(literal);
}
}
//*************************************************************************
//*************************************************************************
template <size_t LiteralSize, size_t BufferSize>
string_ext(const value_type (&literal)[LiteralSize], value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(literal))
{
this->current_size = etl::strlen(literal);
}
else
{
this->assign(literal);
}
}
//*************************************************************************
//*************************************************************************
string_ext(const value_type* text, size_type count, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(text))
{
this->current_size = count;
}
else
{
this->assign(text, text + count);
}
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
string_ext(const value_type* text, size_type count, value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(text))
{
this->current_size = count;
}
else
{
this->assign(text, text + count);
}
}
//*************************************************************************
//*************************************************************************
string_ext(size_type count, value_type c, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
this->initialise();
this->resize(count, c);
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
string_ext(size_type count, value_type c, value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
this->initialise();
this->resize(count, c);
}
//*************************************************************************
//*************************************************************************
explicit string_ext(const etl::string_view& view, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(view.data()))
{
this->current_size = view.size();
}
else
{
this->assign(view.begin(), view.end());
}
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
explicit string_ext(const etl::string_view& view, value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(view.data()))
{
this->current_size = view.size();
}
else
{
this->assign(view.begin(), view.end());
}
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
string_ext(TIterator first, TIterator last, value_type* buffer, size_type buffer_size,
typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: istring(buffer, buffer_size - 1U)
{
if (this->is_within_buffer(etl::addressof(*first)))
{
this->current_size = static_cast<size_type>(etl::distance(first, last));
}
else
{
this->assign(first, last);
}
}
//*************************************************************************
//*************************************************************************
template <typename TIterator, size_t BufferSize>
string_ext(TIterator first, TIterator last, value_type (&buffer)[BufferSize],
typename etl::enable_if<!etl::is_integral<TIterator>::value, int>::type = 0)
: istring(buffer, BufferSize - 1U)
{
if (this->is_within_buffer(etl::addressof(*first)))
{
this->current_size = static_cast<size_type>(etl::distance(first, last));
}
else
{
this->assign(first, last);
}
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
string_ext(std::initializer_list<value_type> init, value_type* buffer, size_type buffer_size)
: istring(buffer, buffer_size - 1U)
{
this->assign(init.begin(), init.end());
}
//*************************************************************************
//*************************************************************************
template <size_t BufferSize>
string_ext(std::initializer_list<value_type> init, value_type (&buffer)[BufferSize])
: istring(buffer, BufferSize - 1U)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
string_ext& operator=(const string_ext& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
//*************************************************************************
string_ext& operator=(const istring& rhs)
{
if (&rhs != this)
{
this->assign(rhs);
}
return *this;
}
//*************************************************************************
//*************************************************************************
string_ext& operator=(const value_type* text)
{
this->assign(text);
return *this;
}
//*************************************************************************
//*************************************************************************
string_ext& operator=(const etl::string_view& view)
{
this->assign(view);
return *this;
}
//*************************************************************************
//*************************************************************************
#if ETL_HAS_ISTRING_REPAIR
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}
private:
//*************************************************************************
//*************************************************************************
string_ext(const string_ext& other) ETL_DELETE;
};
//*************************************************************************
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::istring>
{
size_t operator()(const etl::istring& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
template <size_t SIZE>
struct hash<etl::string<SIZE> >
{
size_t operator()(const etl::string<SIZE>& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
template <>
struct hash<etl::string_ext>
{
size_t operator()(const etl::string_ext& text) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(text.data()),
reinterpret_cast<const uint8_t*>(text.data() + text.size()));
}
};
#endif
//***************************************************************************
//***************************************************************************
template <size_t Array_Size>
etl::string<Array_Size - 1U> make_string(const char (&text)[Array_Size])
{
return etl::string<Array_Size - 1U>(text, etl::strlen(text, Array_Size - 1));
}
//***************************************************************************
//***************************************************************************
template <size_t MAX_SIZE, size_t SIZE>
etl::string<MAX_SIZE> make_string_with_capacity(const char (&text)[SIZE])
{
return etl::string<MAX_SIZE>(text, etl::strlen(text, SIZE));
}
} // namespace etl
#include "private/minmax_pop.h"
#endif
basic_string.h
etl::basic_string_view::data
ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT
Returns a const pointer to the first element of the internal storage.
Definition string_view.h:223
etl::basic_string_view::end
ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT
Returns a const iterator to the end of the array.
Definition string_view.h:247
etl::basic_string_view::begin
ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the array.
Definition string_view.h:231
etl::ibasic_string< char >::is_within_buffer
bool is_within_buffer(const_pointer ptr) const
Definition basic_string.h:2694
etl::ibasic_string< char >::resize
void resize(size_type new_size)
Definition basic_string.h:465
etl::ibasic_string< char >::assign
void assign(const etl::ibasic_string< char > &other)
Definition basic_string.h:670
etl::ibasic_string::data
pointer data()
Definition basic_string.h:633
etl::ibasic_string< char >::initialise
void initialise()
Definition basic_string.h:2465
etl::ibasic_string< char >::repair_buffer
void repair_buffer(char *p_buffer_)
Definition basic_string.h:2477
etl::size_type
etl::string_base::length
size_type length() const
Definition basic_string.h:187
etl::string_base::current_size
size_type current_size
The current number of elements in the string.
Definition basic_string.h:319
etl::string_base::size
size_type size() const
Definition basic_string.h:178
etl::string_ext
Definition string.h:281
etl::string_ext::string_ext
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size, size_type position, size_type length=npos)
Definition string.h:369
etl::string_ext::string_ext
string_ext(const etl::istring &other, value_type(&buffer)[BufferSize])
Definition string.h:350
etl::string_ext::string_ext
string_ext(const value_type(&literal)[LiteralSize], value_type(&buffer)[BufferSize])
Definition string.h:470
etl::string_ext::string_ext
string_ext(value_type *buffer, size_type buffer_size)
Constructor.
Definition string.h:293
etl::string_ext::string_ext
string_ext(const etl::string_ext &other, value_type *buffer, size_type buffer_size)
Definition string.h:314
etl::string_ext::string_ext
string_ext(TPointer text, value_type(&buffer)[BufferSize], typename etl::enable_if< etl::is_same< const value_type *, TPointer >::value, int >::type *=ETL_NULLPTR)
Definition string.h:432
etl::string_ext::string_ext
string_ext(const etl::string_view &view, value_type *buffer, size_type buffer_size)
Definition string.h:551
etl::string_ext::string_ext
string_ext(const etl::string_view &view, value_type(&buffer)[BufferSize])
Definition string.h:570
etl::string_ext::string_ext
string_ext(size_type count, value_type c, value_type *buffer, size_type buffer_size)
Definition string.h:526
etl::string_ext::string_ext
string_ext(const etl::istring &other, value_type *buffer, size_type buffer_size)
Definition string.h:331
etl::string_ext::operator=
string_ext & operator=(const etl::string_view &view)
Assignment operator.
Definition string.h:688
etl::string_ext::string_ext
string_ext(TIterator first, TIterator last, value_type(&buffer)[BufferSize], typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:612
etl::string_ext::string_ext
string_ext(const value_type(&literal)[Size], value_type *buffer, size_type buffer_size)
Definition string.h:451
etl::string_ext::string_ext
string_ext(TPointer text, value_type *buffer, size_type buffer_size, typename etl::enable_if< etl::is_same< const value_type *, TPointer >::value, int >::type *=ETL_NULLPTR)
Definition string.h:412
etl::string_ext::repair
void repair()
Fix the internal pointers after a low level memory copy.
Definition string.h:701
etl::string_ext::operator=
string_ext & operator=(const value_type *text)
Assignment operator.
Definition string.h:678
etl::string_ext::operator=
string_ext & operator=(const istring &rhs)
Assignment operator.
Definition string.h:665
etl::string_ext::string_ext
string_ext(size_type count, value_type c, value_type(&buffer)[BufferSize])
Definition string.h:540
etl::string_ext::string_ext
string_ext(const value_type *text, size_type count, value_type *buffer, size_type buffer_size)
Definition string.h:488
etl::string_ext::string_ext
string_ext(value_type(&buffer)[Size])
Definition string.h:304
etl::string_ext::string_ext
string_ext(const value_type *text, size_type count, value_type(&buffer)[BufferSize])
Definition string.h:508
etl::string_ext::string_ext
string_ext(TIterator first, TIterator last, value_type *buffer, size_type buffer_size, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:590
etl::string_ext::operator=
string_ext & operator=(const string_ext &rhs)
Assignment operator.
Definition string.h:652
etl::string_ext::string_ext
string_ext(const etl::istring &other, value_type(&buffer)[BufferSize], size_type position, size_type length=npos)
Definition string.h:392
etl::string_out_of_bounds
Definition basic_string.h:100
etl::string
Definition string.h:68
etl::string::substr
etl::string< MAX_SIZE_ > substr(size_type position=0, size_type length_=npos) const
Definition string.h:194
etl::string::operator=
string & operator=(const istring &rhs)
Assignment operator.
Definition string.h:226
etl::string::repair
void repair()
Fix the internal pointers after a low level memory copy.
Definition string.h:262
etl::string::operator=
string & operator=(const value_type *text)
Assignment operator.
Definition string.h:239
etl::string::string
string()
Constructor.
Definition string.h:82
etl::string::string
string(TIterator first, TIterator last, typename etl::enable_if<!etl::is_integral< TIterator >::value, int >::type=0)
Definition string.h:162
etl::string::string
string(const etl::string_view &view)
Definition string.h:183
etl::string::string
string(const etl::string< MAX_SIZE_ > &other)
Definition string.h:92
etl::string::string
string(const etl::istring &other)
Definition string.h:102
etl::string::operator=
string & operator=(const string &rhs)
Assignment operator.
Definition string.h:213
etl::string::string
string(const etl::istring &other, size_t position, size_t length=npos)
Definition string.h:114
etl::string::string
string(const value_type *text, size_t count)
Definition string.h:137
etl::string::operator=
string & operator=(const etl::string_view &view)
Assignment operator.
Definition string.h:249
etl::string::string
ETL_EXPLICIT_STRING_FROM_CHAR string(const value_type *text)
Definition string.h:126
etl::string::string
string(size_type count, value_type c)
Definition string.h:148
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::addressof
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
hash.h
initializer_list.h
minmax_pop.h
minmax_push.h
etl
Definition absolute.h:40
etl::make_string
etl::string< Array_Size - 1U > make_string(const char(&text)[Array_Size])
Hash function.
Definition string.h:753
etl::make_string_with_capacity
etl::string< MAX_SIZE > make_string_with_capacity(const char(&text)[SIZE])
Make string with max capacity from string literal or array.
Definition string.h:762
etl::strlen
ETL_CONSTEXPR14 size_t strlen(const T *t) ETL_NOEXCEPT
Alternative strlen for all character types.
Definition char_traits.h:293
platform.h
string_view.h
etl::value_type
etl::type