Add iterators to rexy::string_base

This commit is contained in:
rexy712 2020-08-11 14:05:19 -07:00
parent d90be8e1a8
commit dc68d52dd4

View File

@ -24,6 +24,7 @@
#include <cstddef> //size_t,ptrdiff #include <cstddef> //size_t,ptrdiff
#include <cstring> //strlen #include <cstring> //strlen
#include <climits> //CHAR_BIT #include <climits> //CHAR_BIT
#include <iterator> //reverse_iterator
#include "steal.hpp" #include "steal.hpp"
#include "cx/utility.hpp" #include "cx/utility.hpp"
@ -48,14 +49,17 @@ namespace rexy{
using const_reference = const value_type&; using const_reference = const value_type&;
using iterator = pointer; using iterator = pointer;
using const_iterator = const_pointer; using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
private: private:
static constexpr size_type EXTRA_SDATA_LEN = 0; static constexpr size_type EXTRA_SDATA_LEN = 0;
//represent long string
struct ldata{ struct ldata{
unsigned char islong:1; unsigned char islong:1; //common subsequence with short string
size_type capacity:(CHAR_BIT*sizeof(size_type)-1); size_type capacity:(CHAR_BIT*sizeof(size_type)-1); //take away last bit from capacity for islong
size_type length; size_type length; //length of string excluding null terminator
constexpr ldata(void)noexcept: constexpr ldata(void)noexcept:
islong(0), islong(0),
capacity(0), capacity(0),
@ -63,25 +67,31 @@ namespace rexy{
}; };
static constexpr size_type MAX_SHORT_LEN = EXTRA_SDATA_LEN+sizeof(ldata)-2; static constexpr size_type MAX_SHORT_LEN = EXTRA_SDATA_LEN+sizeof(ldata)-2;
//represent short string
struct sdata{ struct sdata{
unsigned char islong:1; unsigned char islong:1; //common subsequenci with long string
unsigned char length:(CHAR_BIT-1); unsigned char length:(CHAR_BIT-1); //take away last bit from length for islong, excludes null terminator
value_type data[MAX_SHORT_LEN+1]; value_type data[MAX_SHORT_LEN+1]; //char array for string storage
constexpr sdata(void)noexcept: constexpr sdata(void)noexcept:
islong(0), islong(0),
length(0), length(0),
data{}{} data{}{}
}; };
//union of short and long string representations. Default to long representation for static_string's use case.
union combine_data{ union combine_data{
ldata l; ldata l;
sdata s; sdata s;
constexpr combine_data(void)noexcept: constexpr combine_data(void)noexcept:
l(){} l(){}
}m_data; }m_data;
//direct access to current string data regardless of representation. Increases access speed.
pointer m_raw = m_data.s.data; pointer m_raw = m_data.s.data;
protected: protected:
//Functions for handling long vs short string manipulation. Use this instead of directly modifying m_data.
constexpr void set_islong_flag(bool b){ constexpr void set_islong_flag(bool b){
//although well defined to set either one at any time, constexpr functions cannot change active union member.
if(b) if(b)
m_data.l.islong = b; m_data.l.islong = b;
else else
@ -187,9 +197,6 @@ namespace rexy{
//true if m_data is not empty //true if m_data is not empty
constexpr bool valid(void)const noexcept{return length() > 0;} constexpr bool valid(void)const noexcept{return length() > 0;}
constexpr int compare(const string_base& s)const{return cx::strcmp(get(), s.get());}
constexpr int compare(const_pointer s)const{return cx::strcmp(get(), s);}
constexpr reference operator[](size_type i)noexcept{return get_pointer()[i];} constexpr reference operator[](size_type i)noexcept{return get_pointer()[i];}
constexpr const_reference operator[](size_type i)const noexcept{return get_pointer()[i];} constexpr const_reference operator[](size_type i)const noexcept{return get_pointer()[i];}
@ -198,6 +205,20 @@ namespace rexy{
constexpr bool compare(const string_base& s)const{return *this == s;} constexpr bool compare(const string_base& s)const{return *this == s;}
constexpr bool compare(const_pointer c)const{return *this == c;} constexpr bool compare(const_pointer c)const{return *this == c;}
constexpr iterator begin(void){return get_pointer();}
constexpr const_iterator begin(void)const{return get_pointer();}
constexpr iterator end(void){return get_pointer()+length();}
constexpr const_iterator end(void)const{return get_pointer()+length();}
constexpr const_iterator cbegin(void)const{return begin();}
constexpr const_iterator cend(void)const{return end();}
constexpr reverse_iterator rbegin(void){return reverse_iterator(get_pointer()+length());}
constexpr const_reverse_iterator rbegin(void)const{return const_reverse_iterator(get_pointer()+length());}
constexpr reverse_iterator rend(void){return reverse_iterator(get_pointer()-1);}
constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(get_pointer()-1);}
constexpr const_reverse_iterator crbegin(void)const{return rbegin();}
constexpr const_reverse_iterator crend(void)const{return rend();}
static constexpr bool uses_sso(void){return true;} static constexpr bool uses_sso(void){return true;}
static constexpr size_type short_string_size(void){return MAX_SHORT_LEN;} static constexpr size_type short_string_size(void){return MAX_SHORT_LEN;}
}; };