Add iterators to rexy::string_base
This commit is contained in:
parent
d90be8e1a8
commit
dc68d52dd4
@ -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;}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user