diff --git a/opm/parser/eclipse/Deck/DeckRecord.cpp b/opm/parser/eclipse/Deck/DeckRecord.cpp index 0d0e7f92f..d2b53834b 100644 --- a/opm/parser/eclipse/Deck/DeckRecord.cpp +++ b/opm/parser/eclipse/Deck/DeckRecord.cpp @@ -18,6 +18,7 @@ */ +#include #include #include #include @@ -29,8 +30,26 @@ namespace Opm { - DeckRecord::DeckRecord( size_t sz ) { - this->m_items.reserve( sz ); + DeckRecord::DeckRecord( std::vector< DeckItem >&& items ) : + m_items( std::move( items ) ) { + + std::unordered_set< std::string > names; + for( const auto& item : this->m_items ) + names.insert( item.name() ); + + if( names.size() == this->m_items.size() ) + return; + + names.clear(); + std::string msg = "Duplicate item names in DeckRecord:"; + for( const auto& item : this->m_items ) { + if( names.count( item.name() ) != 0 ) + msg += std::string( " " ) += item.name(); + + names.insert( item.name() ); + } + + throw std::invalid_argument( msg ); } size_t DeckRecord::size() const { diff --git a/opm/parser/eclipse/Deck/DeckRecord.hpp b/opm/parser/eclipse/Deck/DeckRecord.hpp index 47e180e38..752f91c3a 100644 --- a/opm/parser/eclipse/Deck/DeckRecord.hpp +++ b/opm/parser/eclipse/Deck/DeckRecord.hpp @@ -33,7 +33,7 @@ namespace Opm { typedef std::vector< DeckItem >::const_iterator const_iterator; DeckRecord() = default; - DeckRecord( size_t ); + DeckRecord( std::vector< DeckItem >&& ); size_t size() const; void addItem( DeckItem&& deckItem ); diff --git a/opm/parser/eclipse/Deck/tests/DeckRecordTests.cpp b/opm/parser/eclipse/Deck/tests/DeckRecordTests.cpp index 26df6c183..e66056142 100644 --- a/opm/parser/eclipse/Deck/tests/DeckRecordTests.cpp +++ b/opm/parser/eclipse/Deck/tests/DeckRecordTests.cpp @@ -71,6 +71,8 @@ BOOST_AUTO_TEST_CASE(addItem_differentItemsSameName_throws) { DeckRecord deckRecord; deckRecord.addItem( mkIntItem( "TEST" ) ); BOOST_CHECK_THROW( deckRecord.addItem( mkIntItem( "TEST" ) ), std::invalid_argument ); + std::vector< DeckItem > items = { mkIntItem( "TEST" ), mkIntItem( "TEST" ) }; + BOOST_CHECK_THROW( DeckRecord( std::move( items ) ), std::invalid_argument ); } BOOST_AUTO_TEST_CASE(get_byIndex_returnsItem) { diff --git a/opm/parser/eclipse/Parser/ParserRecord.cpp b/opm/parser/eclipse/Parser/ParserRecord.cpp index 5056ac6c4..1ae319a06 100644 --- a/opm/parser/eclipse/Parser/ParserRecord.cpp +++ b/opm/parser/eclipse/Parser/ParserRecord.cpp @@ -118,11 +118,10 @@ namespace Opm { } DeckRecord ParserRecord::parse(const ParseContext& parseContext , MessageContainer& msgContainer, RawRecord& rawRecord ) const { - DeckRecord deckRecord( size() + 20 ); - for (size_t i = 0; i < size(); i++) { - auto parserItem = get(i); - deckRecord.addItem( parserItem->scan( rawRecord ) ); - } + std::vector< DeckItem > items; + items.reserve( this->size() + 20 ); + for( const auto& parserItem : *this ) + items.emplace_back( parserItem->scan( rawRecord ) ); if (rawRecord.size() > 0) { std::string msg = "The RawRecord for keyword \"" + rawRecord.getKeywordName() + "\" in file\"" + rawRecord.getFileName() + "\" contained " + @@ -131,7 +130,7 @@ namespace Opm { parseContext.handleError(ParseContext::PARSE_EXTRA_DATA , msgContainer, msg); } - return deckRecord; + return { std::move( items ) }; } bool ParserRecord::equal(const ParserRecord& other) const {