Stringview.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 by Statoil ASA
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef OPM_UTILITY_SUBSTRING_HPP
21#define OPM_UTILITY_SUBSTRING_HPP
22
23#include <algorithm>
24#include <cstring>
25#include <iosfwd>
26#include <stdexcept>
27#include <string>
28
29namespace Opm {
30 /*
31 * string_view is a simple view-into-substring feature whose primary
32 * usecase is to avoid deep copying strings in the inner loops of the
33 * parser. Relies on whatever it's viewing into is kept alive (as all
34 * iterators do):
35 *
36 * auto rec = make_raw_record();
37 * string_view view = rec.getItem( 3 );
38 *
39 * view.size(); view[ 10 ]; // ok
40 * ~rec();
41 * view[ 3 ]; // not ok
42 *
43 * This is desired to fill out a gap in the C++ standard library, since
44 * string_view has yet to be standardised
45 *
46 * http://en.cppreference.com/w/cpp/experimental/basic_string_view
47 */
49 public:
50 using const_iterator = const char*;
51
52 inline string_view() = default;
54 inline string_view( const_iterator, size_t );
55 //cppcheck-suppress noExplicitConstructor
56 inline string_view( const std::string& );
57 inline string_view( const std::string&, size_t );
58 //cppcheck-suppress noExplicitConstructor
59 inline string_view( const char* );
60
61 inline const_iterator begin() const;
62 inline const_iterator end() const;
63
64 inline char front() const;
65 inline char back() const;
66
67 inline char operator[]( size_t ) const;
68 inline bool operator<( const string_view& ) const;
69 inline bool operator==( const string_view& ) const;
70
71 inline bool empty() const;
72 inline size_t size() const;
73 inline size_t length() const;
74
75 inline std::string string() const;
76 inline std::string substr( size_t from = 0 ) const;
77 inline std::string substr( size_t from, size_t len ) const;
78
79 inline bool starts_with(const std::string& str) const;
80 inline std::size_t find(const std::string& substring) const;
81 inline std::size_t find(char c) const;
82 private:
83 const_iterator fst = nullptr;
84 const_iterator lst = nullptr;
85 };
86
87 /*
88 * The implementation of string_view is inline and therefore the definitions
89 * are also in this file. The reason for this is performance; string_view's
90 * logic is trivial and function call and indirection overhead is significant
91 * compared to the useful work it does. Additionally, string_view is a *very*
92 * much used class in the inner loops of the parser - inlining the
93 * implementation measured to improve performance by some 10%.
94 */
95
96
97 // Non-member operators using string_view.
98
99 std::ostream& operator<<( std::ostream& stream, const Opm::string_view& view );
100
102 return str.append( view.begin(), view.end() );
103 }
104
105 inline std::string operator+( const Opm::string_view& view, const std::string& str ) {
106 return view.string().append( str.begin(), str.end() );
107 }
108
109 inline bool operator==( const Opm::string_view& view, const std::string& rhs ) {
110 return rhs.size() == view.size() &&
111 std::equal( view.begin(), view.end(), std::begin( rhs ) );
112 }
113
114 inline bool operator==( const Opm::string_view& view, const char* rhs ) {
115 return std::strlen( rhs ) == view.size() &&
116 std::equal( view.begin(), view.end(), rhs );
117 }
118
119 inline bool operator==( const std::string& lhs, const Opm::string_view& view ) {
120 return view == lhs;
121 }
122
123 inline bool operator==( const char* lhs, const Opm::string_view& view ) {
124 return view == lhs;
125 }
126
127 inline bool operator!=( const Opm::string_view& view, const std::string& rhs ) {
128 return !( view == rhs );
129 }
130
131 inline bool operator!=( const std::string& lhs, const Opm::string_view& view ) {
132 return !( view == lhs );
133 }
134
135 inline bool operator!=( const Opm::string_view& view, const char* rhs ) {
136 return !( view == rhs );
137 }
138
139 inline bool operator!=( const char* lhs, const Opm::string_view& view ) {
140 return !( view == lhs );
141 }
142
143
144 // Member functions of string_view.
145
147 const_iterator last ) :
148 fst( first ),
149 lst( last )
150 {}
151
153 size_t count ) :
154 fst( first ),
155 lst( first + count )
156 {}
157
159 string_view( str.data(), str.size() )
160 {}
161
162 inline string_view::string_view( const std::string& str, size_t count ) :
163 string_view( str.data(), count )
164 {}
165
166 inline string_view::string_view( const char* str ) :
167 string_view( str, str + std::strlen( str ) )
168 {}
169
171 return this->fst;
172 }
173
175 return this->lst;
176 }
177
178 inline char string_view::front() const {
179 return *this->fst;
180 }
181
182 inline char string_view::back() const {
183 return *(this->lst - 1);
184 }
185
186 inline char string_view::operator[]( size_t i ) const {
187 return *(this->begin() + i);
188 }
189
190 inline bool string_view::operator<( const string_view& rhs ) const {
191 return std::lexicographical_compare( this->begin(), this->end(),
192 rhs.begin(), rhs.end() );
193 }
194
195 inline bool string_view::operator==( const string_view& rhs ) const {
196 return std::equal( this->begin(), this->end(), rhs.begin() );
197 }
198
199 inline bool string_view::empty() const {
200 return std::distance( this->begin(), this->end() ) == 0;
201 }
202
203 inline size_t string_view::size() const {
204 return std::distance( this->begin(), this->end() );
205 }
206
207 inline size_t string_view::length() const {
208 return std::distance( this->begin(), this->end() );
209 }
210
212 return this->substr();
213 }
214
215 inline std::string string_view::substr( size_t from ) const {
216 return this->substr( from, this->size() );
217 }
218
219 inline std::string string_view::substr( size_t from, size_t len ) const {
220 if( from > this->size() )
221 throw std::out_of_range( "'from' is greater than length" );
222
223 if (from + len > this->size())
224 return std::string( this->begin() + from, this->lst );
225
226 return std::string( this->begin() + from, this->begin() + len + from);
227 }
228
229 inline std::size_t string_view::find(const std::string& substring) const {
230 auto substring_size = substring.size();
231 if (substring_size > this->size())
232 return std::string::npos;
233
234 auto substring_data = substring.data();
235 auto pos = this->fst;
236 auto last_pos = this->lst - substring.size() + 1;
237
238 while (pos != last_pos) {
239 std::size_t si = 0;
240 while (substring_data[si] == *(pos + si)) {
241 si += 1;
242 if (si == substring_size)
243 return pos - this->fst;
244 }
245 ++pos;
246 }
247
248 return std::string::npos;
249 }
250
251 inline std::size_t string_view::find(char c) const {
252 auto pos = this->fst;
253
254 while (pos != this->lst) {
255 if (*pos == c)
256 return pos - this->fst;
257
258 ++pos;
259 }
260
261 return std::string::npos;
262 }
263
264
265 inline bool string_view::starts_with(const std::string& str) const {
266 auto str_size = str.size();
267 if (str_size > this->size())
268 return false;
269
270 auto str_data = str.data();
271 auto pos = this->fst;
272
273 std::size_t si = 0;
274 while (true) {
275 if (*pos != str_data[si])
276 return false;
277
278 ++pos;
279 ++si;
280
281 if (si == str_size)
282 return true;
283 }
284 }
285
286
287}
288
289#endif //OPM_UTILITY_SUBSTRING_HPP
int count
Definition: cJSON.h:212
const char *const string
Definition: cJSON.h:170
Definition: Stringview.hpp:48
const char * const_iterator
Definition: Stringview.hpp:50
const_iterator end() const
Definition: Stringview.hpp:174
char front() const
Definition: Stringview.hpp:178
bool starts_with(const std::string &str) const
Definition: Stringview.hpp:265
size_t size() const
Definition: Stringview.hpp:203
bool operator<(const string_view &) const
Definition: Stringview.hpp:190
string_view()=default
size_t length() const
Definition: Stringview.hpp:207
char operator[](size_t) const
Definition: Stringview.hpp:186
std::size_t find(const std::string &substring) const
Definition: Stringview.hpp:229
std::string string() const
Definition: Stringview.hpp:211
bool operator==(const string_view &) const
Definition: Stringview.hpp:195
const_iterator begin() const
Definition: Stringview.hpp:170
char back() const
Definition: Stringview.hpp:182
std::string substr(size_t from=0) const
Definition: Stringview.hpp:215
bool empty() const
Definition: Stringview.hpp:199
not_this_one begin(...)
constexpr double from(const double q, const double unit)
Definition: custom-opm-common/opm-common/opm/parser/eclipse/Units/Units.hpp:224
Definition: A.hpp:4
bool operator==(const SummaryConfigNode &lhs, const SummaryConfigNode &rhs)
std::ostream & operator<<(std::ostream &os, const UniformTableLinear< T > &t)
Definition: UniformTableLinear.hpp:249
TimeStampUTC operator+(const TimeStampUTC &lhs, std::chrono::duration< double > delta)
bool operator!=(const SummaryConfigNode &lhs, const SummaryConfigNode &rhs)
Definition: SummaryConfig.hpp:96
T equal(const T v0, const T v1)
Definition: exprtk.hpp:1414
static std::string data()
Definition: exprtk.hpp:40022