21#ifndef G_STRING_FIELD_H
22#define G_STRING_FIELD_H
34 template <
typename T>
class StringFieldT ;
35 template <
typename T>
class StringFieldIteratorT ;
36 using StringField = StringFieldT<std::string> ;
37 using StringFieldView = StringFieldT<std::string_view> ;
55 using char_type =
typename T::value_type ;
57 StringFieldT(
const T & s ,
const char_type * sep , std::size_t sepn ) noexcept ;
71 explicit operator bool()
const noexcept ;
74 bool valid()
const noexcept ;
77 static constexpr bool deref_operator_noexcept = std::is_same<T,std::string_view>::value ;
79 T
operator()()
const noexcept(deref_operator_noexcept) ;
86 const char_type *
data()
const noexcept ;
89 std::size_t
size()
const noexcept ;
92 bool first()
const noexcept ;
95 bool last()
const noexcept ;
98 std::size_t
count()
const noexcept ;
103 StringFieldT( T && s ,
const char * , std::size_t ) = delete ;
113 const char_type * m_sep ;
116 std::size_t m_fendpos ;
131 using iterator_category = std::forward_iterator_tag ;
132 using value_type = T ;
133 using difference_type = int ;
135 using reference = T& ;
148 namespace StringFieldImp
150 template <
typename T>
inline T substr(
const T & s ,
151 std::size_t pos , std::size_t len )
noexcept
153 try {
return s.substr( pos , len ) ; }
catch(...) {
return {} ; }
155 template <> std::string_view
inline substr<std::string_view>(
const std::string_view & s ,
156 std::size_t pos , std::size_t len )
noexcept
158 return sv_substr_noexcept( s , pos , len ) ;
169 m_fpos(s.empty()?std::string::npos:0U) ,
170 m_fendpos(s.find(m_sep,0U,m_sepn))
180 m_fpos(s.empty()?std::string::npos:0U) ,
181 m_fendpos(s.find(m_sep,0U,m_sepn))
188 G_ASSERT( m_fpos != std::string::npos ) ;
189 return m_s.data() + m_fpos ;
195 G_ASSERT( m_fpos != std::string::npos ) ;
196 return (m_fendpos==std::string::npos?m_s.size():m_fendpos) - m_fpos ;
202 return m_fpos != std::string::npos ;
208 return m_fpos != std::string::npos ;
214 if( m_fpos == std::string::npos )
return {} ;
215 return StringFieldImp::substr<T>( m_s , m_fpos , size() ) ;
222 if( m_fpos != std::string::npos )
224 m_fpos = std::min( m_s.size() , m_fpos + m_sepn ) ;
225 m_fendpos = m_s.find( m_sep , m_fpos , m_sepn ) ;
233 return m_fpos == 0U ;
239 return m_fendpos == std::string::npos ;
281 return (f&&f->valid()?f->data():
nullptr) == (other.f&&other.f->valid()?other.f->data():
nullptr) ;
287 return !(*
this == other) ;
292 template <
typename T> StringFieldIteratorT<T> begin( StringFieldT<T> & f )
noexcept
294 return StringFieldIteratorT<T>( f ) ;
300 template <
typename T> StringFieldIteratorT<T> end( StringFieldT<T> & )
noexcept
302 return StringFieldIteratorT<T>(
nullptr ) ;
A standard forward iterator for G::StringFieldT:
A zero-copy string field iterator where the field separators are short fixed strings.
bool first() const noexcept
Returns true if the current field is the first.
bool valid() const noexcept
Returns true if a valid field.
bool last() const noexcept
Returns true if the current field is the last.
StringFieldT< T > & operator++() noexcept
Moves to the next field.
StringFieldT(const T &s, const char_type *sep, std::size_t sepn) noexcept
Constructor.
T operator()() const noexcept(deref_operator_noexcept)
Returns the current field substring.
const char_type * data() const noexcept
Returns the current field pointer.
std::size_t size() const noexcept
Returns the current field size.
std::size_t count() const noexcept
Returns the number of fields.