diff --git a/opm/parser/eclipse/Utility/Stringview.hpp b/opm/parser/eclipse/Utility/Stringview.hpp index 9e983940f..7e699da30 100644 --- a/opm/parser/eclipse/Utility/Stringview.hpp +++ b/opm/parser/eclipse/Utility/Stringview.hpp @@ -72,21 +72,13 @@ namespace Opm { inline size_t size() const; inline size_t length() const; - /* - * substr operations are bounds checked, i.e. if to > from or to > - * size then exceptions are thrown. - * - * returns the substring [from,to), meaning - * view = "sample"; - * view.substr( 0, view.size() ) => sample - * view.substr( 0, 5 ) => sampl - */ inline std::string string() const; inline std::string substr( size_t from = 0 ) const; - inline std::string substr( size_t from, size_t to ) 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; @@ -224,20 +216,16 @@ namespace Opm { return this->substr( from, this->size() ); } - inline std::string string_view::substr( size_t from, size_t to ) const { + 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( to > this->size() ) - throw std::out_of_range( "'to' is greater than length" ); + if (from + len > this->size()) + return std::string( this->begin() + from, this->lst ); - if( from > to ) - throw std::invalid_argument( "'from' is greater than 'to'" ); - - return std::string( this->begin() + from, this->begin() + to ); + 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()) @@ -260,6 +248,19 @@ namespace Opm { 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(); diff --git a/src/opm/parser/eclipse/Parser/Parser.cpp b/src/opm/parser/eclipse/Parser/Parser.cpp index 831266dbf..3c0ff47ca 100644 --- a/src/opm/parser/eclipse/Parser/Parser.cpp +++ b/src/opm/parser/eclipse/Parser/Parser.cpp @@ -579,9 +579,8 @@ bool tryParseKeyword( ParserState& parserState, const Parser& parser, std::uniqu line variable before we check if it is the start of a new keyword. */ - const std::string line_string = line.string(); - auto space_pos = line_string.find(' '); - const std::string candidate_name = line_string.substr(0, space_pos); + auto space_pos = line.find(' '); + const std::string candidate_name = line.substr(0, space_pos); if( parser.isRecognizedKeyword( candidate_name ) ) { rawKeyword->finalizeUnknownSize(); parserState.nextKeyword = line; diff --git a/src/opm/parser/eclipse/RawDeck/StarToken.cpp b/src/opm/parser/eclipse/RawDeck/StarToken.cpp index becd965d1..2d55a9c17 100644 --- a/src/opm/parser/eclipse/RawDeck/StarToken.cpp +++ b/src/opm/parser/eclipse/RawDeck/StarToken.cpp @@ -115,7 +115,7 @@ namespace Opm { if( view.size() < 2 || view[ view.size() - 1 ] != '\'') throw std::invalid_argument("Unable to parse string '" + view + "' as a string token"); - return view.substr( 1, view.size() - 1 ); + return view.substr( 1, view.size() - 2 ); } template<> diff --git a/tests/parser/StringTests.cpp b/tests/parser/StringTests.cpp index f328292d0..2c12f605d 100644 --- a/tests/parser/StringTests.cpp +++ b/tests/parser/StringTests.cpp @@ -108,11 +108,11 @@ BOOST_AUTO_TEST_CASE(viewSubstr) { 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_CHECK_THROW( view.substr( 0, srcstr.size() + 1 ), std::out_of_range ); - BOOST_CHECK_THROW( view.substr( 1, 0 ), std::invalid_argument ); - BOOST_CHECK_NO_THROW( view.substr( 0, 0 ) ); } BOOST_AUTO_TEST_CASE(viewStream) { @@ -174,4 +174,10 @@ BOOST_AUTO_TEST_CASE(strncmp_function) { 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); }