Use value::status to keep track of data status in DeckItem
With this commit the DeckItem::push_backDummyDefault() function will push back a default value T( ). This will give a change in behaviour in downstream code which has used getData<T> to get DeckItem data unchecked.
This commit is contained in:
parent
3156448f99
commit
6cc3b578f5
@ -28,12 +28,15 @@
|
||||
#include <opm/parser/eclipse/Units/Dimension.hpp>
|
||||
#include <opm/parser/eclipse/Utility/Typetools.hpp>
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
#include <opm/parser/eclipse/Deck/value_status.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
class DeckOutput;
|
||||
|
||||
class DeckItem {
|
||||
public:
|
||||
|
||||
DeckItem() = default;
|
||||
DeckItem( const std::string&, int);
|
||||
DeckItem( const std::string&, std::string);
|
||||
@ -59,7 +62,6 @@ namespace Opm {
|
||||
// keyword, though...
|
||||
|
||||
size_t data_size() const;
|
||||
size_t out_size() const;
|
||||
|
||||
template<typename T>
|
||||
T get( size_t index ) const;
|
||||
@ -84,6 +86,8 @@ namespace Opm {
|
||||
void push_backDefault( double );
|
||||
void push_backDefault( std::string );
|
||||
// trying to access the data of a "dummy default item" will raise an exception
|
||||
|
||||
template <typename T>
|
||||
void push_backDummyDefault();
|
||||
|
||||
type_tag getType() const;
|
||||
@ -120,7 +124,7 @@ namespace Opm {
|
||||
type_tag type = type_tag::unknown;
|
||||
|
||||
std::string item_name;
|
||||
std::vector< bool > defaulted;
|
||||
std::vector<value::status> value_status;
|
||||
/*
|
||||
To save space we mutate the dval object in place when asking for SI
|
||||
data; the current state of of the dval member is tracked with the
|
||||
|
@ -105,39 +105,30 @@ const std::string& DeckItem::name() const {
|
||||
}
|
||||
|
||||
bool DeckItem::defaultApplied( size_t index ) const {
|
||||
return this->defaulted.at( index );
|
||||
return value::defaulted( this->value_status.at(index));
|
||||
}
|
||||
|
||||
bool DeckItem::hasValue( size_t index ) const {
|
||||
switch( this->type ) {
|
||||
case type_tag::integer: return this->ival.size() > index;
|
||||
case type_tag::fdouble: return this->dval.size() > index;
|
||||
case type_tag::string: return this->sval.size() > index;
|
||||
case type_tag::uda: return this->uval.size() > index;
|
||||
default: throw std::logic_error( "DeckItem::hasValue: Type not set." );
|
||||
}
|
||||
if (index >= this->value_status.size())
|
||||
return false;
|
||||
|
||||
return value::has_value( this->value_status[index] );
|
||||
}
|
||||
|
||||
size_t DeckItem::data_size() const {
|
||||
switch( this->type ) {
|
||||
case type_tag::integer: return this->ival.size();
|
||||
case type_tag::fdouble: return this->dval.size();
|
||||
case type_tag::string: return this->sval.size();
|
||||
case type_tag::uda: return this->uval.size();
|
||||
default: throw std::logic_error( "DeckItem::size: Type not set." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t DeckItem::out_size() const {
|
||||
size_t data_size = this->data_size();
|
||||
return std::max( data_size , this->defaulted.size() );
|
||||
return this->value_status.size();
|
||||
}
|
||||
|
||||
|
||||
template< typename T >
|
||||
T DeckItem::get( size_t index ) const {
|
||||
return this->value_ref< T >().at( index );
|
||||
if (index >= this->value_status.size())
|
||||
throw std::out_of_range("Invalid index");
|
||||
|
||||
if (!value::has_value(this->value_status[index]))
|
||||
throw std::invalid_argument("Invalid arguemnt");
|
||||
|
||||
return this->value_ref< T >()[index];
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -147,7 +138,7 @@ UDAValue DeckItem::get( size_t index ) const {
|
||||
return value;
|
||||
|
||||
std::size_t dim_index = index % this->active_dimensions.size();
|
||||
if (this->defaulted[index])
|
||||
if (value::defaulted(this->value_status[index]))
|
||||
return UDAValue( value, this->default_dimensions[dim_index]);
|
||||
else
|
||||
return UDAValue( value, this->active_dimensions[dim_index]);
|
||||
@ -165,7 +156,7 @@ void DeckItem::push( T x ) {
|
||||
auto& val = this->value_ref< T >();
|
||||
|
||||
val.push_back( std::move( x ) );
|
||||
this->defaulted.push_back( false );
|
||||
this->value_status.push_back( value::status::deck_value );
|
||||
}
|
||||
|
||||
void DeckItem::push_back( int x ) {
|
||||
@ -189,7 +180,7 @@ void DeckItem::push( T x, size_t n ) {
|
||||
auto& val = this->value_ref< T >();
|
||||
|
||||
val.insert( val.end(), n, x );
|
||||
this->defaulted.insert( this->defaulted.end(), n, false );
|
||||
this->value_status.insert( this->value_status.end(), n, value::status::deck_value );
|
||||
}
|
||||
|
||||
void DeckItem::push_back( int x, size_t n ) {
|
||||
@ -211,12 +202,12 @@ void DeckItem::push_back( UDAValue x, size_t n ) {
|
||||
template< typename T >
|
||||
void DeckItem::push_default( T x ) {
|
||||
auto& val = this->value_ref< T >();
|
||||
if( this->defaulted.size() != val.size() )
|
||||
if( this->value_status.size() != val.size() )
|
||||
throw std::logic_error("To add a value to an item, "
|
||||
"no 'pseudo defaults' can be added before");
|
||||
|
||||
val.push_back( std::move( x ) );
|
||||
this->defaulted.push_back( true );
|
||||
this->value_status.push_back( value::status::valid_default );
|
||||
}
|
||||
|
||||
void DeckItem::push_backDefault( int x ) {
|
||||
@ -236,11 +227,11 @@ void DeckItem::push_backDefault( UDAValue x ) {
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void DeckItem::push_backDummyDefault() {
|
||||
if( !this->defaulted.empty() )
|
||||
throw std::logic_error("Pseudo defaults can only be specified for empty items");
|
||||
|
||||
this->defaulted.push_back( true );
|
||||
auto& val = this->value_ref< T >();
|
||||
val.push_back( T() );
|
||||
this->value_status.push_back( value::status::empty_default );
|
||||
}
|
||||
|
||||
std::string DeckItem::getTrimmedString( size_t index ) const {
|
||||
@ -262,8 +253,13 @@ const std::vector<double>& DeckItem::getData() const {
|
||||
const auto dim_size = this->active_dimensions.size();
|
||||
for( size_t index = 0; index < data.size(); index++ ) {
|
||||
const auto dimIndex = index % dim_size;
|
||||
const auto& dim = this->defaulted[index] ? this->default_dimensions[dimIndex] : this->active_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertSiToRaw( data[ index ] );
|
||||
if (value::defaulted(this->value_status[index])) {
|
||||
const auto& dim = this->default_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertSiToRaw( data[ index ] );
|
||||
} else {
|
||||
const auto& dim = this->active_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertSiToRaw( data[ index ] );
|
||||
}
|
||||
}
|
||||
this->raw_data = true;
|
||||
return data;
|
||||
@ -289,8 +285,13 @@ const std::vector< double >& DeckItem::getSIDoubleData() const {
|
||||
const auto sz = data.size();
|
||||
for( size_t index = 0; index < sz; index++ ) {
|
||||
const auto dimIndex = index % dim_size;
|
||||
const auto& dim = this->defaulted[index] ? this->default_dimensions[dimIndex] : this->active_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertRawToSi( data[ index ] );
|
||||
if (value::defaulted(this->value_status[index])) {
|
||||
const auto& dim = this->default_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertRawToSi( data[ index ] );
|
||||
} else {
|
||||
const auto& dim = this->active_dimensions[dimIndex];
|
||||
data[ index ] = dim.convertRawToSi( data[ index ] );
|
||||
}
|
||||
}
|
||||
this->raw_data = false;
|
||||
return data;
|
||||
@ -305,7 +306,7 @@ type_tag DeckItem::getType() const {
|
||||
|
||||
template< typename T >
|
||||
void DeckItem::write_vector(DeckOutput& stream, const std::vector<T>& data) const {
|
||||
for (size_t index = 0; index < this->out_size(); index++) {
|
||||
for (size_t index = 0; index < this->data_size(); index++) {
|
||||
if (this->defaultApplied(index))
|
||||
stream.stash_default( );
|
||||
else
|
||||
@ -373,7 +374,7 @@ bool DeckItem::equal(const DeckItem& other, bool cmp_default, bool cmp_numeric)
|
||||
return false;
|
||||
|
||||
if (cmp_default)
|
||||
if (this->defaulted != other.defaulted)
|
||||
if (this->value_status != other.value_status)
|
||||
return false;
|
||||
|
||||
switch( this->type ) {
|
||||
@ -469,6 +470,11 @@ template double DeckItem::get< double >( size_t ) const;
|
||||
template std::string DeckItem::get< std::string >( size_t ) const;
|
||||
template UDAValue DeckItem::get< UDAValue >( size_t ) const;
|
||||
|
||||
template void DeckItem::push_backDummyDefault<int>();
|
||||
template void DeckItem::push_backDummyDefault<double>();
|
||||
template void DeckItem::push_backDummyDefault<std::string>();
|
||||
template void DeckItem::push_backDummyDefault<UDAValue>();
|
||||
|
||||
template const std::vector< int >& DeckItem::getData< int >() const;
|
||||
template const std::vector< UDAValue >& DeckItem::getData< UDAValue >() const;
|
||||
template const std::vector< std::string >& DeckItem::getData< std::string >() const;
|
||||
|
@ -55,7 +55,7 @@ namespace Opm {
|
||||
if (parser_item.hasDefault())
|
||||
deck_item.push_back( parser_item.getDefault<T>() );
|
||||
else
|
||||
deck_item.push_backDummyDefault();
|
||||
deck_item.push_backDummyDefault<T>();
|
||||
}
|
||||
else if (input_record[j].is_compatible<T>())
|
||||
deck_item.push_back( input_record[j].get<T>() );
|
||||
|
@ -513,7 +513,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
|
||||
} else {
|
||||
// ... otherwise indicate that the deck item should throw once the
|
||||
// item's data is accessed.
|
||||
deck_item.push_backDummyDefault();
|
||||
deck_item.push_backDummyDefault<T>();
|
||||
}
|
||||
|
||||
return;
|
||||
@ -541,7 +541,7 @@ void scan_item( DeckItem& deck_item, const ParserItem& parser_item, RawRecord& r
|
||||
else if( parser_item.hasDefault() )
|
||||
deck_item.push_backDefault( parser_item.getDefault< T >() );
|
||||
else
|
||||
deck_item.push_backDummyDefault();
|
||||
deck_item.push_backDummyDefault<T>();
|
||||
|
||||
const auto value_start = token.size() - valueString.size();
|
||||
// replace the first occurence of "N*FOO" by a sequence of N-1 times
|
||||
|
@ -166,10 +166,10 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsString) {
|
||||
DeckItem deckStringItem("TEST", std::string() );
|
||||
BOOST_CHECK_EQUAL(deckStringItem.data_size(), 0);
|
||||
|
||||
deckStringItem.push_backDummyDefault();
|
||||
BOOST_CHECK_EQUAL(deckStringItem.data_size(), 0);
|
||||
deckStringItem.push_backDummyDefault<std::string>();
|
||||
BOOST_CHECK_EQUAL(deckStringItem.data_size(), 1);
|
||||
BOOST_CHECK_EQUAL(true, deckStringItem.defaultApplied(0));
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckStringItem.get< std::string >(0), std::invalid_argument);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetStringAtIndex_NoData_ExceptionThrown) {
|
||||
@ -270,10 +270,10 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsDouble) {
|
||||
DeckItem deckDoubleItem( "TEST", double(), dims.first, dims.second);
|
||||
BOOST_CHECK_EQUAL(deckDoubleItem.data_size(), 0);
|
||||
|
||||
deckDoubleItem.push_backDummyDefault();
|
||||
BOOST_CHECK_EQUAL(deckDoubleItem.data_size(), 0);
|
||||
deckDoubleItem.push_backDummyDefault<double>();
|
||||
BOOST_CHECK_EQUAL(deckDoubleItem.data_size(), 1);
|
||||
BOOST_CHECK_EQUAL(true, deckDoubleItem.defaultApplied(0));
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckDoubleItem.get< double >(0), std::invalid_argument);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PushBackMultipleDouble) {
|
||||
@ -344,12 +344,12 @@ BOOST_AUTO_TEST_CASE(DummyDefaultsInt) {
|
||||
DeckItem deckIntItem( "TEST", int() );
|
||||
BOOST_CHECK_EQUAL(deckIntItem.data_size(), 0);
|
||||
|
||||
deckIntItem.push_backDummyDefault();
|
||||
BOOST_CHECK_EQUAL(deckIntItem.data_size(), 0);
|
||||
deckIntItem.push_backDummyDefault<int>();
|
||||
BOOST_CHECK_EQUAL(deckIntItem.data_size(), 1);
|
||||
BOOST_CHECK_EQUAL(true, deckIntItem.defaultApplied(0));
|
||||
BOOST_CHECK_EQUAL( false , deckIntItem.hasValue(0));
|
||||
BOOST_CHECK_EQUAL( false , deckIntItem.hasValue(1));
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(deckIntItem.get< int >(0), std::invalid_argument);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetIntAtIndex_NoData_ExceptionThrown) {
|
||||
|
@ -1247,7 +1247,7 @@ BOOST_AUTO_TEST_CASE(Parse_RawRecordTooFewItems) {
|
||||
BOOST_CHECK_NO_THROW(parserRecord.parse(parseContext, errors, rawRecord, unit_system, unit_system, "KEWYORD", "filename"));
|
||||
auto record = parserRecord.parse(parseContext, errors , rawRecord, unit_system, unit_system, "KEYWORD", "filename");
|
||||
BOOST_CHECK_NO_THROW(record.getItem(2));
|
||||
BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::out_of_range);
|
||||
BOOST_CHECK_THROW(record.getItem(2).get< int >(0), std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1099,7 +1099,7 @@ BOOST_AUTO_TEST_CASE(createDeckWithWeltArgException2) {
|
||||
TableManager table ( deck );
|
||||
Eclipse3DProperties eclipseProperties ( deck , table, grid);
|
||||
Runspec runspec (deck);
|
||||
BOOST_CHECK_THROW(Schedule(deck, grid , eclipseProperties, runspec), std::out_of_range);
|
||||
BOOST_CHECK_THROW(Schedule(deck, grid , eclipseProperties, runspec), std::invalid_argument);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(createDeckWithWPIMULT) {
|
||||
|
@ -1012,7 +1012,7 @@ VFPPROD \n\
|
||||
auto units = Opm::UnitSystem::newMETRIC();
|
||||
BOOST_CHECK_EQUAL(deck.count("VFPPROD"), 1);
|
||||
|
||||
BOOST_CHECK_THROW(Opm::VFPProdTable(vfpprodKeyword, units), std::out_of_range);
|
||||
BOOST_CHECK_THROW(Opm::VFPProdTable(vfpprodKeyword, units), std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user