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<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,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(std::is_same<T,string_view>::value)
153 return s.substr( pos , len ) ;
155 template <> string_view
inline substr<string_view>(
const string_view & s ,
156 std::size_t pos , std::size_t len )
noexcept
158 return sv_substr( s , pos , len ) ;
160 static_assert( !
noexcept(std::string().substr(0,0)) ,
"" ) ;
161 static_assert(
noexcept(sv_substr(string_view(),0,0)) ,
"" ) ;
171 m_fpos(s.empty()?std::string::npos:0U) ,
172 m_fendpos(s.find(m_sep,0U,m_sepn))
182 m_fpos(s.empty()?std::string::npos:0U) ,
183 m_fendpos(s.find(m_sep,0U,m_sepn))
190 G_ASSERT( m_fpos != std::string::npos ) ;
191 return m_s.data() + m_fpos ;
197 G_ASSERT( m_fpos != std::string::npos ) ;
198 return (m_fendpos==std::string::npos?m_s.size():m_fendpos) - m_fpos ;
204 return m_fpos != std::string::npos ;
210 return m_fpos != std::string::npos ;
216 if( m_fpos == std::string::npos )
return {} ;
217 return StringFieldImp::substr<T>( m_s , m_fpos , size() ) ;
224 if( m_fpos != std::string::npos )
226 m_fpos = std::min( m_s.size() , m_fpos + m_sepn ) ;
227 m_fendpos = m_s.find( m_sep , m_fpos , m_sepn ) ;
235 return m_fpos == 0U ;
241 return m_fendpos == std::string::npos ;
283 return (f&&f->valid()?f->data():
nullptr) == (other.f&&other.f->valid()?other.f->data():
nullptr) ;
289 return !(*
this == other) ;
294 template <
typename T> StringFieldIteratorT<T> begin( StringFieldT<T> & f )
noexcept
296 return StringFieldIteratorT<T>( f ) ;
302 template <
typename T> StringFieldIteratorT<T> end( StringFieldT<T> & )
noexcept
304 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.