diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index bbe2ea2cd..84b15882c 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -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 diff --git a/GenerateKeywords.cmake b/GenerateKeywords.cmake index 1ef0a4280..6d845783f 100644 --- a/GenerateKeywords.cmake +++ b/GenerateKeywords.cmake @@ -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 diff --git a/opm/parser/eclipse/Parser/Parser.hpp b/opm/parser/eclipse/Parser/Parser.hpp index 8a8b0e621..140fdaaea 100644 --- a/opm/parser/eclipse/Parser/Parser.hpp +++ b/opm/parser/eclipse/Parser/Parser.hpp @@ -34,7 +34,6 @@ #include #include -#include 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 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 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> code_keywords; }; diff --git a/opm/parser/eclipse/Parser/ParserKeyword.hpp b/opm/parser/eclipse/Parser/ParserKeyword.hpp index b072c1b03..093620624 100644 --- a/opm/parser/eclipse/Parser/ParserKeyword.hpp +++ b/opm/parser/eclipse/Parser/ParserKeyword.hpp @@ -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 ); diff --git a/opm/parser/eclipse/Utility/Stringview.hpp b/opm/parser/eclipse/Utility/Stringview.hpp deleted file mode 100644 index 7e699da30..000000000 --- a/opm/parser/eclipse/Utility/Stringview.hpp +++ /dev/null @@ -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 . - */ - -#ifndef OPM_UTILITY_SUBSTRING_HPP -#define OPM_UTILITY_SUBSTRING_HPP - -#include -#include -#include -#include -#include - -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 diff --git a/src/opm/parser/eclipse/Parser/Parser.cpp b/src/opm/parser/eclipse/Parser/Parser.cpp index 3a0e81678..69ffd87ed 100644 --- a/src/opm/parser/eclipse/Parser/Parser.cpp +++ b/src/opm/parser/eclipse/Parser/Parser.cpp @@ -48,7 +48,6 @@ #include #include #include -#include #include #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>& code_keywords, const std::string& str ) { auto count = std::count_if(code_keywords.begin(), code_keywords.end(), [&str](const std::pair& code_pair) { @@ -236,26 +258,26 @@ inline std::string clean( const std::vector> 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> -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 tryParseKeyword( ParserState& parserState, const Parser& parser) { bool is_title = false; std::unique_ptr 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 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 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 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 Parser::getAllDeckNames () const { std::vector 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; } diff --git a/src/opm/parser/eclipse/Parser/ParserItem.cpp b/src/opm/parser/eclipse/Parser/ParserItem.cpp index 6d230b6a5..0d11935c3 100644 --- a/src/opm/parser/eclipse/Parser/ParserItem.cpp +++ b/src/opm/parser/eclipse/Parser/ParserItem.cpp @@ -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(); 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; diff --git a/src/opm/parser/eclipse/Parser/ParserKeyword.cpp b/src/opm/parser/eclipse/Parser/ParserKeyword.cpp index f95cd16b9..007cabc7c 100644 --- a/src/opm/parser/eclipse/Parser/ParserKeyword.cpp +++ b/src/opm/parser/eclipse/Parser/ParserKeyword.cpp @@ -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()) diff --git a/src/opm/parser/eclipse/Parser/raw/RawKeyword.hpp b/src/opm/parser/eclipse/Parser/raw/RawKeyword.hpp index 708745ee6..de8b883e3 100644 --- a/src/opm/parser/eclipse/Parser/raw/RawKeyword.hpp +++ b/src/opm/parser/eclipse/Parser/raw/RawKeyword.hpp @@ -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); diff --git a/src/opm/parser/eclipse/Parser/raw/RawRecord.cpp b/src/opm/parser/eclipse/Parser/raw/RawRecord.cpp index 9aaecd4d4..37e8dc9f6 100644 --- a/src/opm/parser/eclipse/Parser/raw/RawRecord.cpp +++ b/src/opm/parser/eclipse/Parser/raw/RawRecord.cpp @@ -23,8 +23,6 @@ #include #include -#include - #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); } } diff --git a/src/opm/parser/eclipse/Parser/raw/RawRecord.hpp b/src/opm/parser/eclipse/Parser/raw/RawRecord.hpp index dda439716..33bdbfa70 100644 --- a/src/opm/parser/eclipse/Parser/raw/RawRecord.hpp +++ b/src/opm/parser/eclipse/Parser/raw/RawRecord.hpp @@ -23,10 +23,9 @@ #include #include #include +#include #include -#include - 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 ); } } diff --git a/src/opm/parser/eclipse/Parser/raw/StarToken.cpp b/src/opm/parser/eclipse/Parser/raw/StarToken.cpp index 6d667c690..caa6b2d50 100644 --- a/src/opm/parser/eclipse/Parser/raw/StarToken.cpp +++ b/src/opm/parser/eclipse/Parser/raw/StarToken.cpp @@ -26,7 +26,6 @@ #include -#include #include #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( string_view view ) { - return { view.string() }; + RawString readValueToken( 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(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(cnt); } diff --git a/src/opm/parser/eclipse/Parser/raw/StarToken.hpp b/src/opm/parser/eclipse/Parser/raw/StarToken.hpp index 094f2f3e4..3f9dfd273 100644 --- a/src/opm/parser/eclipse/Parser/raw/StarToken.hpp +++ b/src/opm/parser/eclipse/Parser/raw/StarToken.hpp @@ -23,27 +23,26 @@ #include #include -#include #include namespace Opm { - bool isStarToken(const string_view& token, + bool isStarToken(const std::string_view& token, std::string& countString, std::string& valueString); template - 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; diff --git a/src/opm/parser/eclipse/Utility/Stringview.cpp b/src/opm/parser/eclipse/Utility/Stringview.cpp deleted file mode 100644 index 0b06858ef..000000000 --- a/src/opm/parser/eclipse/Utility/Stringview.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -#include - -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; -} diff --git a/tests/parser/ParserTests.cpp b/tests/parser/ParserTests.cpp index 59fbecee9..34f254f1b 100644 --- a/tests/parser/ParserTests.cpp +++ b/tests/parser/ParserTests.cpp @@ -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; diff --git a/tests/parser/RawKeywordTests.cpp b/tests/parser/RawKeywordTests.cpp index 35cc95594..5a9873a41 100644 --- a/tests/parser/RawKeywordTests.cpp +++ b/tests/parser/RawKeywordTests.cpp @@ -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); diff --git a/tests/parser/StringTests.cpp b/tests/parser/StringTests.cpp index a79caf787..0838fe51e 100644 --- a/tests/parser/StringTests.cpp +++ b/tests/parser/StringTests.cpp @@ -3,7 +3,6 @@ #include #include -#include 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" ); }