Replace opm implementation of string_view with std::string_view

This commit is contained in:
Joakim Hove 2020-07-14 12:33:29 +02:00
parent bdd74b33b2
commit 3e1411bf87
17 changed files with 157 additions and 572 deletions

View File

@ -193,7 +193,6 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/Units/Dimension.cpp
src/opm/parser/eclipse/Units/UnitSystem.cpp
src/opm/parser/eclipse/Utility/Functional.cpp
src/opm/parser/eclipse/Utility/Stringview.cpp
)
@ -543,7 +542,6 @@ if(ENABLE_ECL_INPUT)
list(APPEND PUBLIC_HEADER_FILES
opm/io/eclipse/SummaryNode.hpp
opm/json/JsonObject.hpp
opm/parser/eclipse/Utility/Stringview.hpp
opm/parser/eclipse/Utility/Functional.hpp
opm/parser/eclipse/Utility/Typetools.hpp
opm/parser/eclipse/Generator/KeywordGenerator.hpp

View File

@ -20,7 +20,6 @@ set(genkw_SOURCES src/opm/json/JsonObject.cpp
src/opm/parser/eclipse/Parser/raw/StarToken.cpp
src/opm/parser/eclipse/Units/Dimension.cpp
src/opm/parser/eclipse/Units/UnitSystem.cpp
src/opm/parser/eclipse/Utility/Stringview.cpp
src/opm/common/OpmLog/OpmLog.cpp
src/opm/common/OpmLog/Logger.cpp
src/opm/common/OpmLog/StreamLog.cpp

View File

@ -34,7 +34,6 @@
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
namespace Json {
class JsonObject;
@ -85,8 +84,8 @@ namespace Opm {
bool hasKeyword( const std::string& ) const;
const ParserKeyword& getKeyword(const std::string& name) const;
bool isRecognizedKeyword( const string_view& deckKeywordName) const;
const ParserKeyword& getParserKeywordFromDeckName(const string_view& deckKeywordName) const;
bool isRecognizedKeyword( const std::string_view& deckKeywordName) const;
const ParserKeyword& getParserKeywordFromDeckName(const std::string_view& deckKeywordName) const;
std::vector<std::string> getAllDeckNames () const;
void loadKeywords(const Json::JsonObject& jsonKeywords);
@ -135,18 +134,18 @@ namespace Opm {
private:
bool hasWildCardKeyword(const std::string& keyword) const;
const ParserKeyword* matchingKeyword(const string_view& keyword) const;
const ParserKeyword* matchingKeyword(const std::string_view& keyword) const;
void addDefaultKeywords();
// std::vector< std::unique_ptr< const ParserKeyword > > keyword_storage;
std::list<ParserKeyword> keyword_storage;
// associative map of deck names and the corresponding ParserKeyword object
std::map< string_view, const ParserKeyword* > m_deckParserKeywords;
std::map< std::string_view, const ParserKeyword* > m_deckParserKeywords;
// associative map of the parser internal names and the corresponding
// ParserKeyword object for keywords which match a regular expression
std::map< string_view, const ParserKeyword* > m_wildCardKeywords;
std::map< std::string_view, const ParserKeyword* > m_wildCardKeywords;
std::vector<std::pair<std::string,std::string>> code_keywords;
};

View File

@ -39,7 +39,6 @@ namespace Opm {
class ErrorGuard;
class ParserDoubleItem;
class RawKeyword;
class string_view;
class ErrorGuard;
/*
@ -91,10 +90,10 @@ namespace Opm {
static bool validInternalName(const std::string& name);
static bool validDeckName(const string_view& name);
static bool validDeckName(const std::string_view& name);
bool hasMatchRegex() const;
void setMatchRegex(const std::string& deckNameRegexp);
bool matches(const string_view& ) const;
bool matches(const std::string_view& ) const;
bool hasDimension() const;
void addRecord( ParserRecord );
void addDataRecord( ParserRecord );
@ -159,7 +158,7 @@ namespace Opm {
bool double_records = false;
std::string code_end;
static bool validNameStart(const string_view& name);
static bool validNameStart(const std::string_view& name);
void initDeckNames( const Json::JsonObject& jsonConfig );
void initSectionNames( const Json::JsonObject& jsonConfig );
void initMatchRegex( const Json::JsonObject& jsonObject );

View File

@ -1,289 +0,0 @@
/*
Copyright (C) 2016 by Statoil ASA
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_UTILITY_SUBSTRING_HPP
#define OPM_UTILITY_SUBSTRING_HPP
#include <algorithm>
#include <cstring>
#include <iosfwd>
#include <stdexcept>
#include <string>
namespace Opm {
/*
* string_view is a simple view-into-substring feature whose primary
* usecase is to avoid deep copying strings in the inner loops of the
* parser. Relies on whatever it's viewing into is kept alive (as all
* iterators do):
*
* auto rec = make_raw_record();
* string_view view = rec.getItem( 3 );
*
* view.size(); view[ 10 ]; // ok
* ~rec();
* view[ 3 ]; // not ok
*
* This is desired to fill out a gap in the C++ standard library, since
* string_view has yet to be standardised
*
* http://en.cppreference.com/w/cpp/experimental/basic_string_view
*/
class string_view {
public:
using const_iterator = const char*;
inline string_view() = default;
inline string_view( const_iterator, const_iterator );
inline string_view( const_iterator, size_t );
//cppcheck-suppress noExplicitConstructor
inline string_view( const std::string& );
inline string_view( const std::string&, size_t );
//cppcheck-suppress noExplicitConstructor
inline string_view( const char* );
inline const_iterator begin() const;
inline const_iterator end() const;
inline char front() const;
inline char back() const;
inline char operator[]( size_t ) const;
inline bool operator<( const string_view& ) const;
inline bool operator==( const string_view& ) const;
inline bool empty() const;
inline size_t size() const;
inline size_t length() const;
inline std::string string() const;
inline std::string substr( size_t from = 0 ) const;
inline std::string substr( size_t from, size_t len ) const;
inline bool starts_with(const std::string& str) const;
inline std::size_t find(const std::string& substring) const;
inline std::size_t find(char c) const;
private:
const_iterator fst = nullptr;
const_iterator lst = nullptr;
};
/*
* The implementation of string_view is inline and therefore the definitions
* are also in this file. The reason for this is performance; string_view's
* logic is trivial and function call and indirection overhead is significant
* compared to the useful work it does. Additionally, string_view is a *very*
* much used class in the inner loops of the parser - inlining the
* implementation measured to improve performance by some 10%.
*/
// Non-member operators using string_view.
std::ostream& operator<<( std::ostream& stream, const Opm::string_view& view );
inline std::string operator+( std::string str, const Opm::string_view& view ) {
return str.append( view.begin(), view.end() );
}
inline std::string operator+( const Opm::string_view& view, const std::string& str ) {
return view.string().append( str.begin(), str.end() );
}
inline bool operator==( const Opm::string_view& view, const std::string& rhs ) {
return rhs.size() == view.size() &&
std::equal( view.begin(), view.end(), std::begin( rhs ) );
}
inline bool operator==( const Opm::string_view& view, const char* rhs ) {
return std::strlen( rhs ) == view.size() &&
std::equal( view.begin(), view.end(), rhs );
}
inline bool operator==( const std::string& lhs, const Opm::string_view& view ) {
return view == lhs;
}
inline bool operator==( const char* lhs, const Opm::string_view& view ) {
return view == lhs;
}
inline bool operator!=( const Opm::string_view& view, const std::string& rhs ) {
return !( view == rhs );
}
inline bool operator!=( const std::string& lhs, const Opm::string_view& view ) {
return !( view == lhs );
}
inline bool operator!=( const Opm::string_view& view, const char* rhs ) {
return !( view == rhs );
}
inline bool operator!=( const char* lhs, const Opm::string_view& view ) {
return !( view == lhs );
}
// Member functions of string_view.
inline string_view::string_view( const_iterator first,
const_iterator last ) :
fst( first ),
lst( last )
{}
inline string_view::string_view( const_iterator first ,
size_t count ) :
fst( first ),
lst( first + count )
{}
inline string_view::string_view( const std::string& str ) :
string_view( str.data(), str.size() )
{}
inline string_view::string_view( const std::string& str, size_t count ) :
string_view( str.data(), count )
{}
inline string_view::string_view( const char* str ) :
string_view( str, str + std::strlen( str ) )
{}
inline string_view::const_iterator string_view::begin() const {
return this->fst;
}
inline string_view::const_iterator string_view::end() const {
return this->lst;
}
inline char string_view::front() const {
return *this->fst;
}
inline char string_view::back() const {
return *(this->lst - 1);
}
inline char string_view::operator[]( size_t i ) const {
return *(this->begin() + i);
}
inline bool string_view::operator<( const string_view& rhs ) const {
return std::lexicographical_compare( this->begin(), this->end(),
rhs.begin(), rhs.end() );
}
inline bool string_view::operator==( const string_view& rhs ) const {
return std::equal( this->begin(), this->end(), rhs.begin() );
}
inline bool string_view::empty() const {
return std::distance( this->begin(), this->end() ) == 0;
}
inline size_t string_view::size() const {
return std::distance( this->begin(), this->end() );
}
inline size_t string_view::length() const {
return std::distance( this->begin(), this->end() );
}
inline std::string string_view::string() const {
return this->substr();
}
inline std::string string_view::substr( size_t from ) const {
return this->substr( from, this->size() );
}
inline std::string string_view::substr( size_t from, size_t len ) const {
if( from > this->size() )
throw std::out_of_range( "'from' is greater than length" );
if (from + len > this->size())
return std::string( this->begin() + from, this->lst );
return std::string( this->begin() + from, this->begin() + len + from);
}
inline std::size_t string_view::find(const std::string& substring) const {
auto substring_size = substring.size();
if (substring_size > this->size())
return std::string::npos;
auto substring_data = substring.data();
auto pos = this->fst;
auto last_pos = this->lst - substring.size() + 1;
while (pos != last_pos) {
std::size_t si = 0;
while (substring_data[si] == *(pos + si)) {
si += 1;
if (si == substring_size)
return pos - this->fst;
}
++pos;
}
return std::string::npos;
}
inline std::size_t string_view::find(char c) const {
auto pos = this->fst;
while (pos != this->lst) {
if (*pos == c)
return pos - this->fst;
++pos;
}
return std::string::npos;
}
inline bool string_view::starts_with(const std::string& str) const {
auto str_size = str.size();
if (str_size > this->size())
return false;
auto str_data = str.data();
auto pos = this->fst;
std::size_t si = 0;
while (true) {
if (*pos != str_data[si])
return false;
++pos;
++si;
if (si == str_size)
return true;
}
}
}
#endif //OPM_UTILITY_SUBSTRING_HPP

View File

@ -48,7 +48,6 @@
#include <opm/parser/eclipse/Parser/ParserItem.hpp>
#include <opm/parser/eclipse/Parser/ParserKeyword.hpp>
#include <opm/parser/eclipse/Parser/ParserRecord.hpp>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
#include <opm/common/utility/String.hpp>
#include "raw/RawConsts.hpp"
@ -109,9 +108,10 @@ inline Itr find_terminator( Itr begin, Itr end, Term terminator ) {
ABC '--Comment1' --Comment2 => ABC '--Comment1'
ABC "-- Not balanced quote? => ABC "-- Not balanced quote?
*/
static inline string_view strip_comments( string_view str ) {
return { str.begin(),
find_terminator( str.begin(), str.end(), find_comment() ) };
static inline std::string_view strip_comments( std::string_view str ) {
auto terminator = find_terminator( str.begin(), str.end(), find_comment() );
std::size_t size = std::distance(str.begin(), terminator);
return { str.begin(), size };
}
template< typename Itr >
@ -128,14 +128,15 @@ inline Itr trim_right( Itr begin, Itr end ) {
return std::find_if_not( rbegin, rend, RawConsts::is_separator() ).base();
}
inline string_view trim( string_view str ) {
inline std::string_view trim( std::string_view str ) {
auto fst = trim_left( str.begin(), str.end() );
auto lst = trim_right( fst, str.end() );
return { fst, lst };
std::size_t size = std::distance(fst, lst);
return { fst, size };
}
inline string_view del_after_first_slash( string_view view ) {
using itr = string_view::const_iterator;
inline std::string_view del_after_first_slash( std::string_view view ) {
using itr = std::string_view::const_iterator;
const auto term = []( itr begin, itr end ) {
return std::find( begin, end, '/' );
};
@ -146,11 +147,11 @@ inline string_view del_after_first_slash( string_view view ) {
/* we want to preserve terminating slashes */
if( slash != end ) ++slash;
return { begin, slash };
std::size_t size = std::distance(begin, slash);
return { begin, size };
}
inline string_view del_after_last_slash( string_view view ) {
inline std::string_view del_after_last_slash( std::string_view view ) {
auto begin = view.begin();
auto end = view.end();
auto slash = end;
@ -169,11 +170,11 @@ inline string_view del_after_last_slash( string_view view ) {
/* we want to preserve terminating slashes */
if( slash != end ) ++slash;
return { begin, slash };
std::size_t size = std::distance(begin, slash);
return { begin, size };
}
inline string_view del_after_slash(string_view view, bool raw_strings) {
inline std::string_view del_after_slash(std::string_view view, bool raw_strings) {
if (raw_strings)
return del_after_last_slash(view);
else
@ -181,13 +182,13 @@ inline string_view del_after_slash(string_view view, bool raw_strings) {
}
inline bool getline( string_view& input, string_view& line ) {
inline bool getline( std::string_view& input, std::string_view& line ) {
if( input.empty() ) return false;
auto end = std::find( input.begin(), input.end(), '\n' );
line = string_view( input.begin(), end );
input = string_view( end + 1, input.end() );
line = std::string_view( input.begin(), end - input.begin() );
input = std::string_view( end + 1, input.end() - (end + 1));
return true;
/* we know that we always append a newline onto the input string, so we can
@ -206,7 +207,7 @@ inline std::string fast_clean( const std::string& str ) {
std::string dst;
dst.resize( str.size() );
string_view input( str ), line;
std::string_view input( str ), line;
auto dsti = dst.begin();
while( true ) {
@ -224,6 +225,27 @@ inline std::string fast_clean( const std::string& str ) {
return dst;
}
inline bool starts_with(const std::string_view& view, const std::string& str) {
auto str_size = str.size();
if (str_size > view.size())
return false;
auto str_data = str.data();
auto pos = view.begin();
std::size_t si = 0;
while (true) {
if (*pos != str_data[si])
return false;
++pos;
++si;
if (si == str_size)
return true;
}
}
inline std::string clean( const std::vector<std::pair<std::string, std::string>>& code_keywords, const std::string& str ) {
auto count = std::count_if(code_keywords.begin(), code_keywords.end(), [&str](const std::pair<std::string, std::string>& code_pair)
{
@ -236,26 +258,26 @@ inline std::string clean( const std::vector<std::pair<std::string, std::string>>
std::string dst;
dst.resize( str.size() );
string_view input( str ), line;
std::string_view input( str ), line;
auto dsti = dst.begin();
while( true ) {
for (const auto& code_pair : code_keywords) {
const auto& keyword = code_pair.first;
if (input.starts_with(keyword)) {
if (starts_with(input, keyword)) {
std::string end_string = code_pair.second;
auto end_pos = input.find(end_string);
if (end_pos == std::string::npos) {
std::copy(input.begin(), input.end(), dsti);
dsti += std::distance( input.begin(), input.end() );
input = string_view(input.end(), input.end());
input = std::string_view(input.end(), 0);
break;
} else {
end_pos += end_string.size();
std::copy(input.begin(), input.begin() + end_pos, dsti);
dsti += end_pos;
*dsti++ = '\n';
input = string_view(input.begin() + end_pos + 1, input.end());
input = std::string_view(input.begin() + end_pos + 1, input.end() - (input.begin() + end_pos + 1));
break;
}
}
@ -280,25 +302,27 @@ inline std::string clean( const std::vector<std::pair<std::string, std::string>>
inline std::string make_deck_name(const string_view& str) {
inline std::string make_deck_name(const std::string_view& str) {
auto first_sep = std::find_if( str.begin(), str.end(), RawConsts::is_separator() );
return uppercase( str.substr(0, first_sep - str.begin()) );
return uppercase( std::string( str.substr( 0, first_sep - str.begin()) ));
}
inline string_view update_record_buffer(const string_view& record_buffer, const string_view& line) {
inline std::string_view update_record_buffer(const std::string_view& record_buffer, const std::string_view& line) {
if (record_buffer.empty())
return line;
else
return { record_buffer.begin(), line.end() };
else {
std::size_t size = std::distance(record_buffer.begin(), line.end());
return { record_buffer.begin(), size };
}
}
inline bool isTerminator(const string_view& line) {
inline bool isTerminator(const std::string_view& line) {
return (line.size() == 1 && line.back() == RawConsts::slash);
}
inline bool isTerminatedRecordString(const string_view& line) {
inline bool isTerminatedRecordString(const std::string_view& line) {
return (line.back() == RawConsts::slash);
}
@ -309,7 +333,7 @@ struct file {
input( in ), path( p )
{}
string_view input;
std::string_view input;
size_t lineNR = 0;
Opm::filesystem::path path;
};
@ -338,7 +362,7 @@ class ParserState {
void loadFile( const Opm::filesystem::path& );
void openRootFile( const Opm::filesystem::path& );
void handleRandomText(const string_view& ) const;
void handleRandomText(const std::string_view& ) const;
Opm::filesystem::path getIncludeFilePath( std::string ) const;
void addPathAlias( const std::string& alias, const std::string& path );
@ -346,8 +370,8 @@ class ParserState {
size_t line() const;
bool done() const;
string_view getline();
void ungetline(const string_view& ln);
std::string_view getline();
void ungetline(const std::string_view& ln);
void closeFile();
private:
@ -385,8 +409,8 @@ bool ParserState::done() const {
return this->input_stack.empty();
}
string_view ParserState::getline() {
string_view ln;
std::string_view ParserState::getline() {
std::string_view ln;
str::getline( this->input_stack.top().input, ln );
this->input_stack.top().lineNR++;
@ -396,12 +420,12 @@ string_view ParserState::getline() {
void ParserState::ungetline(const string_view& line) {
void ParserState::ungetline(const std::string_view& line) {
auto& file_view = this->input_stack.top().input;
if (line.end() + 1 != file_view.begin())
throw std::invalid_argument("line view does not immediately proceed file_view");
file_view = string_view(line.begin(), file_view.end());
file_view = std::string_view(line.begin(), file_view.end() - line.begin());
this->input_stack.top().lineNR--;
}
@ -489,10 +513,10 @@ void ParserState::loadFile(const Opm::filesystem::path& inputFile) {
* of the data section of any keyword.
*/
void ParserState::handleRandomText(const string_view& keywordString ) const {
void ParserState::handleRandomText(const std::string_view& keywordString ) const {
std::string errorKey;
std::stringstream msg;
std::string trimmedCopy = keywordString.string();
std::string trimmedCopy = std::string( keywordString );
if (trimmedCopy == "/") {
@ -636,7 +660,7 @@ RawKeyword * newRawKeyword(const ParserKeyword& parserKeyword, const std::string
}
RawKeyword * newRawKeyword( const std::string& deck_name, ParserState& parserState, const Parser& parser, const string_view& line ) {
RawKeyword * newRawKeyword( const std::string& deck_name, ParserState& parserState, const Parser& parser, const std::string_view& line ) {
if (deck_name.size() > RawConsts::maxKeywordLength) {
const std::string keyword8 = deck_name.substr(0, RawConsts::maxKeywordLength);
if (parser.isRecognizedKeyword(keyword8)) {
@ -701,7 +725,7 @@ void skipUDT( ParserState& parserState, const Parser& parser) {
std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Parser& parser) {
bool is_title = false;
std::unique_ptr<RawKeyword> rawKeyword;
string_view record_buffer(str::emptystr);
std::string_view record_buffer(str::emptystr);
while( !parserState.done() ) {
auto line = parserState.getline();
@ -755,7 +779,7 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
if (rawKeyword->getSizeType() == Raw::CODE) {
auto end_pos = line.find(parserKeyword.codeEnd());
if (end_pos != std::string::npos) {
string_view line_content = { line.begin(), line.begin() + end_pos};
std::string_view line_content = { line.begin(), end_pos};
record_buffer = str::update_record_buffer( record_buffer, line_content );
RawRecord record(record_buffer, true);
@ -797,7 +821,8 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
RawRecord record("opm/flow simulation");
rawKeyword->addRecord(record);
} else {
RawRecord record( string_view{ record_buffer.begin(), record_buffer.end()});
std::size_t size = std::distance(record_buffer.begin(),record_buffer.end());
RawRecord record( std::string_view{ record_buffer.begin(), size });
rawKeyword->addRecord(record);
}
return rawKeyword;
@ -811,7 +836,8 @@ std::unique_ptr<RawKeyword> tryParseKeyword( ParserState& parserState, const Par
if (str::isTerminatedRecordString(record_buffer)) {
RawRecord record( string_view{ record_buffer.begin(), record_buffer.end( ) - 1});
std::size_t size = std::distance(record_buffer.begin(), record_buffer.end()) - 1;
RawRecord record( std::string_view{ record_buffer.begin(), size });
if (rawKeyword->addRecord(record))
return rawKeyword;
@ -1029,7 +1055,7 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
return m_deckParserKeywords.size();
}
const ParserKeyword* Parser::matchingKeyword(const string_view& name) const {
const ParserKeyword* Parser::matchingKeyword(const std::string_view& name) const {
for (auto iter = m_wildCardKeywords.begin(); iter != m_wildCardKeywords.end(); ++iter) {
if (iter->second->matches(name))
return iter->second;
@ -1041,7 +1067,7 @@ bool parseState( ParserState& parserState, const Parser& parser ) {
return (m_wildCardKeywords.count(internalKeywordName) > 0);
}
bool Parser::isRecognizedKeyword(const string_view& name ) const {
bool Parser::isRecognizedKeyword(const std::string_view& name ) const {
if( !ParserKeyword::validDeckName( name ) )
return false;
@ -1059,7 +1085,7 @@ void Parser::addParserKeyword( ParserKeyword&& parserKeyword ) {
* * A keyword can be added that overwrites some *but not all* deckname ->
* keyword mappings. Keeping track of this is more hassle than worth for
* what is essentially edge case usage.
* * We can store (and search) via string_view's from the keyword added
* * We can store (and search) via std::string_view's from the keyword added
* first because we know that it will be kept around, i.e. we don't have to
* deal with subtle lifetime issues.
* * It means we aren't reliant on some internal name mapping, and can only
@ -1071,7 +1097,7 @@ void Parser::addParserKeyword( ParserKeyword&& parserKeyword ) {
this->keyword_storage.push_back( std::move( parserKeyword ) );
const ParserKeyword * ptr = std::addressof(this->keyword_storage.back());
string_view name( ptr->getName() );
std::string_view name( ptr->getName() );
for (auto nameIt = ptr->deckNamesBegin();
nameIt != ptr->deckNamesEnd();
@ -1093,15 +1119,15 @@ void Parser::addParserKeyword(const Json::JsonObject& jsonKeyword) {
}
bool Parser::hasKeyword( const std::string& name ) const {
return this->m_deckParserKeywords.find( string_view( name ) )
return this->m_deckParserKeywords.find( std::string_view( name ) )
!= this->m_deckParserKeywords.end();
}
const ParserKeyword& Parser::getKeyword( const std::string& name ) const {
return getParserKeywordFromDeckName( string_view( name ) );
return getParserKeywordFromDeckName( std::string_view( name ) );
}
const ParserKeyword& Parser::getParserKeywordFromDeckName(const string_view& name ) const {
const ParserKeyword& Parser::getParserKeywordFromDeckName(const std::string_view& name ) const {
auto candidate = m_deckParserKeywords.find( name );
if( candidate != m_deckParserKeywords.end() ) return *candidate->second;
@ -1109,7 +1135,7 @@ const ParserKeyword& Parser::getParserKeywordFromDeckName(const string_view& nam
const auto* wildCardKeyword = matchingKeyword( name );
if ( !wildCardKeyword )
throw std::invalid_argument( "Do not have parser keyword for parsing: " + name );
throw std::invalid_argument( "Do not have parser keyword for parsing: " + std::string(name) );
return *wildCardKeyword;
}
@ -1117,10 +1143,10 @@ const ParserKeyword& Parser::getParserKeywordFromDeckName(const string_view& nam
std::vector<std::string> Parser::getAllDeckNames () const {
std::vector<std::string> keywords;
for (auto iterator = m_deckParserKeywords.begin(); iterator != m_deckParserKeywords.end(); iterator++) {
keywords.push_back(iterator->first.string());
keywords.push_back(std::string(iterator->first));
}
for (auto iterator = m_wildCardKeywords.begin(); iterator != m_wildCardKeywords.end(); iterator++) {
keywords.push_back(iterator->first.string());
keywords.push_back(std::string(iterator->first));
}
return keywords;
}

View File

@ -463,7 +463,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
if (parse_raw) {
while (record.size()) {
auto token = record.pop_front();
auto raw_string = RawString{ token.string() };
auto raw_string = RawString{ std::string(token) };
deck_item.push_back( raw_string );
}
return;
@ -516,7 +516,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
if (parse_raw) {
auto token = record.pop_front();
auto raw_string = RawString{ token.string() };
auto raw_string = RawString{ std::string(token) };
deck_item.push_back( raw_string );
return;
}
@ -541,15 +541,16 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
deck_item.push_backDummyDefault<T>();
const auto value_start = token.size() - valueString.size();
const std::size_t size = token.end() - (token.begin() + value_start);
// replace the first occurence of "N*FOO" by a sequence of N-1 times
// "FOO". this is slightly hacky, but it makes it work if the
// number of defaults pass item boundaries...
// We can safely make a string_view of one_star because it
// We can safely make a std::string_view of one_star because it
// has static storage
static const char* one_star = "1*";
string_view rep = !st.hasValue()
? string_view{ one_star }
: string_view{ token.begin() + value_start, token.end() };
std::string_view rep = !st.hasValue()
? std::string_view{ one_star }
: std::string_view{ token.begin() + value_start, size };
record.prepend( st.count() - 1, rep );
return;

View File

@ -249,7 +249,7 @@ namespace Opm {
}
bool ParserKeyword::validNameStart( const string_view& name) {
bool ParserKeyword::validNameStart( const std::string_view& name) {
if (!isalpha(name[0]))
return false;
@ -266,7 +266,7 @@ namespace Opm {
}
bool ParserKeyword::validDeckName( const string_view& name) {
bool ParserKeyword::validDeckName( const std::string_view& name) {
if( !validNameStart( name ) )
return false;
@ -651,11 +651,11 @@ void set_dimensions( ParserItem& item,
}
}
bool ParserKeyword::matches(const string_view& name ) const {
bool ParserKeyword::matches(const std::string_view& name ) const {
if (!validDeckName(name ))
return false;
else if( m_deckNames.count( name.string() ) )
else if( m_deckNames.count( std::string(name) ) )
return true;
else if (hasMatchRegex())

View File

@ -33,8 +33,6 @@
namespace Opm {
class RawRecord;
class string_view;
class RawKeyword {
public:
RawKeyword(const std::string& name, const std::string& filename, std::size_t lineNR, bool raw_string, Raw::KeywordSizeEnum sizeType);

View File

@ -23,8 +23,6 @@
#include <vector>
#include <deque>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
#include "RawRecord.hpp"
#include "RawConsts.hpp"
@ -36,23 +34,25 @@ namespace Opm {
namespace {
std::deque< string_view > splitSingleRecordString( const string_view& record ) {
auto first_nonspace = []( string_view::const_iterator begin,
string_view::const_iterator end ) {
std::deque< std::string_view > splitSingleRecordString( const std::string_view& record ) {
auto first_nonspace = []( std::string_view::const_iterator begin,
std::string_view::const_iterator end ) {
return std::find_if_not( begin, end, RawConsts::is_separator() );
};
std::deque< string_view > dst;
std::deque< std::string_view > dst;
auto current = record.begin();
while( (current = first_nonspace( current, record.end() )) != record.end() )
{
if( *current == RawConsts::quote ) {
auto quote_end = std::find( current + 1, record.end(), RawConsts::quote ) + 1;
dst.push_back( { current, quote_end } );
std::size_t size = std::distance(current, quote_end);
dst.push_back( { current, size} );
current = quote_end;
} else {
auto token_end = std::find_if( current, record.end(), RawConsts::is_separator() );
dst.push_back( { current, token_end } );
std::size_t size = std::distance(current, token_end);
dst.push_back( { current, size } );
current = token_end;
}
}
@ -77,7 +77,7 @@ inline bool even_quotes( const T& str ) {
}
RawRecord::RawRecord(const string_view& singleRecordString, bool text) :
RawRecord::RawRecord(const std::string_view& singleRecordString, bool text) :
m_sanitizedRecordString( singleRecordString )
{
@ -88,29 +88,19 @@ inline bool even_quotes( const T& str ) {
if( !even_quotes( singleRecordString ) )
throw std::invalid_argument("Input string is not a complete record string, "
"offending string: '" + singleRecordString + "'");
"offending string: '" + std::string(singleRecordString) + "'");
}
}
RawRecord::RawRecord(const string_view& singleRecordString) :
RawRecord::RawRecord(const std::string_view& singleRecordString) :
RawRecord(singleRecordString, false)
{}
void RawRecord::prepend( size_t count, string_view tok ) {
void RawRecord::prepend( size_t count, std::string_view tok ) {
this->m_recordItems.insert( this->m_recordItems.begin(), count, tok );
}
void RawRecord::dump() const {
std::cout << "RecordDump: ";
for (size_t i = 0; i < m_recordItems.size(); i++) {
std::cout
<< this->m_recordItems[i] << "/"
<< getItem( i ) << " ";
}
std::cout << std::endl;
}
std::string RawRecord::getRecordString() const {
return m_sanitizedRecordString.string();
return std::string(m_sanitizedRecordString);
}
}

View File

@ -23,10 +23,9 @@
#include <deque>
#include <memory>
#include <string>
#include <string_view>
#include <list>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
namespace Opm {
/// Class representing the lowest level of the Raw datatypes, a record. A record is simply
@ -35,36 +34,34 @@ namespace Opm {
class RawRecord {
public:
RawRecord( const string_view&, bool text);
explicit RawRecord( const string_view&);
RawRecord( const std::string_view&, bool text);
explicit RawRecord( const std::string_view&);
inline string_view pop_front();
inline string_view front() const;
void push_front( string_view token );
void prepend( size_t count, string_view token );
inline std::string_view pop_front();
inline std::string_view front() const;
void push_front( std::string_view token );
void prepend( size_t count, std::string_view token );
inline size_t size() const;
std::string getRecordString() const;
inline string_view getItem(size_t index) const;
void dump() const;
inline std::string_view getItem(size_t index) const;
private:
string_view m_sanitizedRecordString;
std::deque< string_view > m_recordItems;
std::string_view m_sanitizedRecordString;
std::deque< std::string_view > m_recordItems;
};
/*
* These are frequently called, but fairly trivial in implementation, and
* inlining the calls gives a decent low-effort performance benefit.
*/
string_view RawRecord::pop_front() {
std::string_view RawRecord::pop_front() {
auto front = m_recordItems.front();
this->m_recordItems.pop_front();
return front;
}
string_view RawRecord::front() const {
std::string_view RawRecord::front() const {
return this->m_recordItems.front();
}
@ -72,7 +69,7 @@ namespace Opm {
return m_recordItems.size();
}
string_view RawRecord::getItem(size_t index) const {
std::string_view RawRecord::getItem(size_t index) const {
return this->m_recordItems.at( index );
}
}

View File

@ -26,7 +26,6 @@
#include <boost/spirit/include/qi.hpp>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
#include "StarToken.hpp"
@ -35,7 +34,7 @@ namespace qi = boost::spirit::qi;
namespace Opm {
bool isStarToken(const string_view& token,
bool isStarToken(const std::string_view& token,
std::string& countString,
std::string& valueString) {
// find first character which is not a digit
@ -60,25 +59,25 @@ namespace Opm {
// possible.)
else if (pos == 0) {
countString = "";
valueString = token.substr(pos + 1);
valueString = std::string(token.substr(pos + 1));
return true;
}
// if a star is prefixed by an unsigned integer N, then this should be
// interpreted as "repeat value after star N times"
countString = token.substr(0, pos);
valueString = token.substr(pos + 1);
countString = std::string(token.substr(0, pos));
valueString = std::string(token.substr(pos + 1));
return true;
}
template<>
int readValueToken< int >( string_view view ) {
int readValueToken< int >( std::string_view view ) {
int n = 0;
auto cursor = view.begin();
const bool ok = qi::parse( cursor, view.end(), qi::int_, n );
if( ok && cursor == view.end() ) return n;
throw std::invalid_argument( "Malformed integer '" + view + "'" );
throw std::invalid_argument( "Malformed integer '" + std::string(view) + "'" );
}
template< typename T >
@ -97,36 +96,36 @@ namespace Opm {
};
template<>
double readValueToken< double >( string_view view ) {
double readValueToken< double >( std::string_view view ) {
double n = 0;
qi::real_parser< double, fortran_double< double > > double_;
auto cursor = view.begin();
const auto ok = qi::parse( cursor, view.end(), double_, n );
if( ok && cursor == view.end() ) return n;
throw std::invalid_argument( "Malformed floating point number '" + view + "'" );
throw std::invalid_argument( "Malformed floating point number '" + std::string(view) + "'" );
}
template <>
std::string readValueToken< std::string >( string_view view ) {
std::string readValueToken< std::string >( std::string_view view ) {
if( view.size() == 0 || view[ 0 ] != '\'' )
return view.string();
return std::string(view);
if( view.size() < 2 || view[ view.size() - 1 ] != '\'')
throw std::invalid_argument("Unable to parse string '" + view + "' as a string token");
throw std::invalid_argument("Unable to parse string '" + std::string(view) + "' as a string token");
return view.substr( 1, view.size() - 2 );
return std::string(view.substr(1, view.size() - 2 ));
}
template <>
RawString readValueToken<RawString>( string_view view ) {
return { view.string() };
RawString readValueToken<RawString>( std::string_view view ) {
return { std::string( view ) };
}
template<>
UDAValue readValueToken< UDAValue >( string_view view ) {
UDAValue readValueToken< UDAValue >( std::string_view view ) {
double n = 0;
qi::real_parser< double, fortran_double< double > > double_;
auto cursor = view.begin();
@ -136,13 +135,13 @@ namespace Opm {
return UDAValue( readValueToken<std::string>(view) );
}
void StarToken::init_( const string_view& token ) {
void StarToken::init_( const std::string_view& token ) {
// special-case the interpretation of a lone star as "1*" but do not
// allow constructs like "*123"...
if (m_countString == "") {
if (m_valueString != "")
// TODO: decorate the deck with a warning instead?
throw std::invalid_argument("Not specifying a count also implies not specifying a value. Token: \'" + token + "\'.");
throw std::invalid_argument("Not specifying a count also implies not specifying a value. Token: \'" + std::string(token) + "\'.");
// TODO: since this is explicitly forbidden by the documentation it might
// be a good idea to decorate the deck with a warning?
@ -153,7 +152,7 @@ namespace Opm {
if (cnt < 1)
// TODO: decorate the deck with a warning instead?
throw std::invalid_argument("Specifing zero repetitions is not allowed. Token: \'" + token + "\'.");
throw std::invalid_argument("Specifing zero repetitions is not allowed. Token: \'" + std::string(token) + "\'.");
m_count = static_cast<std::size_t>(cnt);
}

View File

@ -23,27 +23,26 @@
#include <cctype>
#include <string>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
#include <opm/parser/eclipse/Utility/Typetools.hpp>
namespace Opm {
bool isStarToken(const string_view& token,
bool isStarToken(const std::string_view& token,
std::string& countString,
std::string& valueString);
template <class T>
T readValueToken( string_view );
T readValueToken( std::string_view );
class StarToken {
public:
StarToken(const string_view& token)
StarToken(const std::string_view& token)
{
if (!isStarToken(token, m_countString, m_valueString))
throw std::invalid_argument("Token \""+ token +"\" is not a repetition specifier");
throw std::invalid_argument("Token \""+ std::string(token) +"\" is not a repetition specifier");
init_(token);
}
StarToken(const string_view& token, const std::string& countStr, const std::string& valueStr)
StarToken(const std::string_view& token, const std::string& countStr, const std::string& valueStr)
: m_countString(countStr)
, m_valueString(valueStr)
{
@ -77,7 +76,7 @@ public:
private:
// internal initialization method. the m_countString and m_valueString attributes
// must be set before calling this method.
void init_(const string_view& token);
void init_(const std::string_view& token);
std::size_t m_count;
std::string m_countString;

View File

@ -1,9 +0,0 @@
#include <iterator>
#include <ostream>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
std::ostream& Opm::operator<<( std::ostream& stream, const Opm::string_view& view ) {
std::copy( view.begin(), view.end(), std::ostream_iterator< char >( stream ) );
return stream;
}

View File

@ -1054,14 +1054,14 @@ BOOST_AUTO_TEST_CASE(parse_validRecord_noThrow) {
auto record = createSimpleParserRecord();
ParseContext parseContext;
ErrorGuard errors;
RawRecord raw( string_view( "100 443" ) );
RawRecord raw( std::string_view( "100 443" ) );
UnitSystem unit_system;
BOOST_CHECK_NO_THROW(record.parse(parseContext, errors, raw , unit_system, unit_system, "KEYWORD", "filename") );
}
BOOST_AUTO_TEST_CASE(parse_validRecord_deckRecordCreated) {
auto record = createSimpleParserRecord();
RawRecord rawRecord( string_view( "100 443" ) );
RawRecord rawRecord( std::string_view( "100 443" ) );
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;
@ -1093,7 +1093,7 @@ static ParserRecord createMixedParserRecord() {
BOOST_AUTO_TEST_CASE(parse_validMixedRecord_noThrow) {
auto record = createMixedParserRecord();
RawRecord rawRecord( string_view( "1 2 10.0 20.0 4 90.0") );
RawRecord rawRecord( std::string_view( "1 2 10.0 20.0 4 90.0") );
ParseContext parseContext;
ErrorGuard errors;
UnitSystem unit_system;

View File

@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(RawKeywordConstructor) {
BOOST_AUTO_TEST_CASE(IsFinished) {
std::string storage = "RecordString";
string_view line(storage);
std::string_view line(storage);
RawRecord rec(line);
RawKeyword kw1("NAME", "file", 10, false, Raw::FIXED, 0);

View File

@ -3,7 +3,6 @@
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/String.hpp>
#include <opm/parser/eclipse/Utility/Stringview.hpp>
using namespace Opm;
@ -41,145 +40,24 @@ BOOST_AUTO_TEST_CASE( uppercase_move ) {
BOOST_AUTO_TEST_CASE( uppercase_mixed_type ) {
std::string src = "string";
string_view view( src );
std::string_view view( src );
std::string dst = "string";
uppercase( view, dst );
BOOST_CHECK_EQUAL( dst, "STRING" );
BOOST_CHECK_EQUAL( view, "string" );
BOOST_CHECK( view == "string" );
}
BOOST_AUTO_TEST_CASE( write_parts_of_dst ) {
std::string src = "string";
string_view view( src );
std::string_view view( src );
std::string dst = "stringmixed";
uppercase( view, dst );
BOOST_CHECK_EQUAL( dst, "STRINGmixed" );
BOOST_CHECK_EQUAL( view, "string" );
}
BOOST_AUTO_TEST_CASE(fullStringView) {
std::string srcstr = "lorem ipsum";
string_view view( srcstr );
BOOST_CHECK_EQUAL_COLLECTIONS(
srcstr.begin(), srcstr.end(),
view.begin(), view.end() );
}
BOOST_AUTO_TEST_CASE(viewCorrectSize) {
std::string srcstr = "lorem ipsum";
string_view full( srcstr );
BOOST_CHECK_EQUAL( srcstr.size(), full.size() );
string_view view( srcstr, 5 );
BOOST_CHECK_EQUAL( 5, view.size() );
BOOST_CHECK_EQUAL( 5, view.length() );
}
BOOST_AUTO_TEST_CASE(viewOperatorAt) {
std::string srcstr = "lorem ipsum";
string_view view( srcstr );
for( size_t i = 0; i < view.size(); ++i )
BOOST_CHECK_EQUAL( view[ i ], srcstr[ i ] );
}
BOOST_AUTO_TEST_CASE(viewFrontBack) {
std::string srcstr = "lorem ipsum";
string_view view( srcstr );
BOOST_CHECK_EQUAL( view.front(), 'l' );
BOOST_CHECK_EQUAL( view.back(), 'm' );
}
BOOST_AUTO_TEST_CASE(viewSubstr) {
std::string srcstr = "lorem ipsum";
string_view view( srcstr );
BOOST_CHECK_NO_THROW( view.string() );
BOOST_CHECK_EQUAL( srcstr, view.string() );
BOOST_CHECK_EQUAL( srcstr, view.substr() );
BOOST_CHECK_EQUAL( "", view.substr( 0, 0 ) );
BOOST_CHECK_EQUAL( srcstr.substr( 1 ), view.substr( 1 ) );
BOOST_CHECK_EQUAL( srcstr, view.substr( 0, srcstr.size() + 1 ));
BOOST_CHECK_EQUAL( "", view.substr( 1, 0 ));
BOOST_CHECK_EQUAL( "", view.substr( 0, 0 ) );
BOOST_CHECK_THROW( view.substr( srcstr.size() + 1 ), std::out_of_range );
}
BOOST_AUTO_TEST_CASE(viewStream) {
std::string srcstr = "lorem ipsum";
string_view view( srcstr );
std::stringstream str;
str << view;
BOOST_CHECK_EQUAL( srcstr, str.str() );
}
BOOST_AUTO_TEST_CASE(equalityOperators) {
std::string srcstr = "lorem ipsum";
std::string diffstr = "lorem";
string_view view( srcstr );
BOOST_CHECK_EQUAL( srcstr, view );
BOOST_CHECK_NE( diffstr, view );
BOOST_CHECK_EQUAL( view, srcstr );
BOOST_CHECK_NE( view, diffstr );
BOOST_CHECK_EQUAL( "lorem ipsum", view );
BOOST_CHECK_NE( "lorem", view );
BOOST_CHECK_EQUAL( view, "lorem ipsum" );
BOOST_CHECK_NE( view, "lorem" );
}
BOOST_AUTO_TEST_CASE(plusOperator) {
std::string total = "lorem ipsum";
std::string lhs = "lorem";
std::string ws = " ";
std::string rhs = "ipsum";
string_view lhs_view( lhs );
string_view rhs_view( rhs );
BOOST_CHECK_EQUAL( total, lhs_view + ws + rhs_view );
BOOST_CHECK_EQUAL( lhs + ws, lhs_view + ws );
BOOST_CHECK_EQUAL( ws + rhs, ws + rhs_view );
}
BOOST_AUTO_TEST_CASE(strncmp_function) {
std::string s = "A BB CCC DDDD";
string_view view(s);
BOOST_CHECK(!view.starts_with("this is a very long string -longer than the view"));
BOOST_CHECK(view.starts_with("A"));
BOOST_CHECK(view.starts_with("A BB"));
BOOST_CHECK(!view.starts_with("A BB D"));
BOOST_CHECK(view.starts_with(s));
BOOST_CHECK_EQUAL( view.find("A"), 0);
BOOST_CHECK_EQUAL( view.find("BB"), 2);
BOOST_CHECK_EQUAL( view.find("C"), 5);
BOOST_CHECK_EQUAL( view.find("CCCC"), std::string::npos);
BOOST_CHECK_EQUAL( view.find("DDDD"), 9);
BOOST_CHECK_EQUAL( view.find('A'), 0);
BOOST_CHECK_EQUAL( view.find('B'), 2);
BOOST_CHECK_EQUAL( view.find('C'), 5);
BOOST_CHECK_EQUAL( view.find('X'), std::string::npos);
BOOST_CHECK_EQUAL( view.find('D'), 9);
BOOST_CHECK( view == "string" );
}