mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-29 09:45:32 +00:00
Merge branch 'esm_variant' into 'master'
Use std::variant for ESM::Variant implementation See merge request OpenMW/openmw!719
This commit is contained in:
commit
301411c5c5
5 changed files with 148 additions and 498 deletions
|
@ -180,19 +180,19 @@ namespace
|
||||||
|
|
||||||
TEST(ESMVariantGetStringTest, for_default_constructed_should_throw_exception)
|
TEST(ESMVariantGetStringTest, for_default_constructed_should_throw_exception)
|
||||||
{
|
{
|
||||||
ASSERT_THROW(Variant().getString(), std::runtime_error);
|
ASSERT_THROW(Variant().getString(), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantGetStringTest, for_constructed_from_int_should_throw_exception)
|
TEST(ESMVariantGetStringTest, for_constructed_from_int_should_throw_exception)
|
||||||
{
|
{
|
||||||
const Variant variant(int{42});
|
const Variant variant(int{42});
|
||||||
ASSERT_THROW(variant.getString(), std::runtime_error);
|
ASSERT_THROW(variant.getString(), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantGetStringTest, for_constructed_from_float_should_throw_exception)
|
TEST(ESMVariantGetStringTest, for_constructed_from_float_should_throw_exception)
|
||||||
{
|
{
|
||||||
const Variant variant(float{2.7});
|
const Variant variant(float{2.7});
|
||||||
ASSERT_THROW(variant.getString(), std::runtime_error);
|
ASSERT_THROW(variant.getString(), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantGetStringTest, for_constructed_from_string_should_return_same_value)
|
TEST(ESMVariantGetStringTest, for_constructed_from_string_should_return_same_value)
|
||||||
|
@ -372,40 +372,40 @@ namespace
|
||||||
TEST(ESMVariantSetStringTest, for_default_constructed_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_default_constructed_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_unknown_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_unknown_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
variant.setType(VT_Unknown);
|
variant.setType(VT_Unknown);
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_default_int_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_default_int_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant(int{13});
|
Variant variant(int{13});
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_int_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_int_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
variant.setType(VT_Int);
|
variant.setType(VT_Int);
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_short_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_short_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
variant.setType(VT_Short);
|
variant.setType(VT_Short);
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_float_should_throw_exception)
|
TEST(ESMVariantSetStringTest, for_float_should_throw_exception)
|
||||||
{
|
{
|
||||||
Variant variant(float{2.7f});
|
Variant variant(float{2.7f});
|
||||||
ASSERT_THROW(variant.setString("foo"), std::runtime_error);
|
ASSERT_THROW(variant.setString("foo"), std::bad_variant_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ESMVariantSetStringTest, for_string_should_change_value)
|
TEST(ESMVariantSetStringTest, for_string_should_change_value)
|
||||||
|
@ -420,7 +420,6 @@ namespace
|
||||||
Variant mVariant;
|
Variant mVariant;
|
||||||
Variant::Format mFormat;
|
Variant::Format mFormat;
|
||||||
std::size_t mDataSize {};
|
std::size_t mDataSize {};
|
||||||
std::size_t mDataHash {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string write(const Variant& variant, const Variant::Format format)
|
std::string write(const Variant& variant, const Variant::Format format)
|
||||||
|
@ -442,11 +441,10 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant writeAndRead(const Variant& variant, const Variant::Format format, std::size_t dataSize, std::size_t dataHash)
|
Variant writeAndRead(const Variant& variant, const Variant::Format format, std::size_t dataSize)
|
||||||
{
|
{
|
||||||
const std::string data = write(variant, format);
|
const std::string data = write(variant, format);
|
||||||
EXPECT_EQ(data.size(), dataSize);
|
EXPECT_EQ(data.size(), dataSize);
|
||||||
EXPECT_EQ(std::hash<std::string>{}(data), dataHash);
|
|
||||||
return read(format, data);
|
return read(format, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,20 +453,20 @@ namespace
|
||||||
TEST_P(ESMVariantToESMTest, deserialized_is_equal_to_serialized)
|
TEST_P(ESMVariantToESMTest, deserialized_is_equal_to_serialized)
|
||||||
{
|
{
|
||||||
const auto param = GetParam();
|
const auto param = GetParam();
|
||||||
const auto result = writeAndRead(param.mVariant, param.mFormat, param.mDataSize, param.mDataHash);
|
const auto result = writeAndRead(param.mVariant, param.mFormat, param.mDataSize);
|
||||||
ASSERT_EQ(param.mVariant, result);
|
ASSERT_EQ(param.mVariant, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(VariantAndData, ESMVariantToESMTest, Values(
|
INSTANTIATE_TEST_SUITE_P(VariantAndData, ESMVariantToESMTest, Values(
|
||||||
WriteToESMTestCase {Variant(), Variant::Format_Gmst, 324, 10398667754238537314ul},
|
WriteToESMTestCase {Variant(), Variant::Format_Gmst, 324},
|
||||||
WriteToESMTestCase {Variant(int{42}), Variant::Format_Global, 345, 2440845426097842853ul},
|
WriteToESMTestCase {Variant(int{42}), Variant::Format_Global, 345},
|
||||||
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Global, 345, 8428720798053904009ul},
|
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Global, 345},
|
||||||
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Info, 336, 11930997575130354755ul},
|
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Info, 336},
|
||||||
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Local, 336, 11930997575130354755ul},
|
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Local, 336},
|
||||||
WriteToESMTestCase {makeVariant(VT_Short, 42), Variant::Format_Global, 345, 7812065815960720679ul},
|
WriteToESMTestCase {makeVariant(VT_Short, 42), Variant::Format_Global, 345},
|
||||||
WriteToESMTestCase {makeVariant(VT_Short, 42), Variant::Format_Local, 334, 5017869102981712080ul},
|
WriteToESMTestCase {makeVariant(VT_Short, 42), Variant::Format_Local, 334},
|
||||||
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Info, 336, 12560431547347287906ul},
|
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Info, 336},
|
||||||
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Local, 336, 12560431547347287906ul}
|
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Local, 336}
|
||||||
));
|
));
|
||||||
|
|
||||||
struct ESMVariantToESMNoneTest : TestWithParam<WriteToESMTestCase> {};
|
struct ESMVariantToESMNoneTest : TestWithParam<WriteToESMTestCase> {};
|
||||||
|
@ -476,14 +474,14 @@ namespace
|
||||||
TEST_P(ESMVariantToESMNoneTest, deserialized_is_none)
|
TEST_P(ESMVariantToESMNoneTest, deserialized_is_none)
|
||||||
{
|
{
|
||||||
const auto param = GetParam();
|
const auto param = GetParam();
|
||||||
const auto result = writeAndRead(param.mVariant, param.mFormat, param.mDataSize, param.mDataHash);
|
const auto result = writeAndRead(param.mVariant, param.mFormat, param.mDataSize);
|
||||||
ASSERT_EQ(Variant(), result);
|
ASSERT_EQ(Variant(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(VariantAndData, ESMVariantToESMNoneTest, Values(
|
INSTANTIATE_TEST_SUITE_P(VariantAndData, ESMVariantToESMNoneTest, Values(
|
||||||
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Gmst, 336, 11930997575130354755ul},
|
WriteToESMTestCase {Variant(float{2.7f}), Variant::Format_Gmst, 336},
|
||||||
WriteToESMTestCase {Variant(std::string("foo")), Variant::Format_Gmst, 335, 7604528240659685057ul},
|
WriteToESMTestCase {Variant(std::string("foo")), Variant::Format_Gmst, 335},
|
||||||
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Gmst, 336, 12560431547347287906ul}
|
WriteToESMTestCase {makeVariant(VT_Int, 42), Variant::Format_Gmst, 336}
|
||||||
));
|
));
|
||||||
|
|
||||||
struct ESMVariantWriteToESMFailTest : TestWithParam<WriteToESMTestCase> {};
|
struct ESMVariantWriteToESMFailTest : TestWithParam<WriteToESMTestCase> {};
|
||||||
|
|
|
@ -14,106 +14,53 @@ namespace
|
||||||
const uint32_t INTV = ESM::FourCC<'I','N','T','V'>::value;
|
const uint32_t INTV = ESM::FourCC<'I','N','T','V'>::value;
|
||||||
const uint32_t FLTV = ESM::FourCC<'F','L','T','V'>::value;
|
const uint32_t FLTV = ESM::FourCC<'F','L','T','V'>::value;
|
||||||
const uint32_t STTV = ESM::FourCC<'S','T','T','V'>::value;
|
const uint32_t STTV = ESM::FourCC<'S','T','T','V'>::value;
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant::Variant() : mType (VT_None), mData (nullptr) {}
|
template <typename T, bool orDefault = false>
|
||||||
|
struct GetValue
|
||||||
ESM::Variant::Variant(const std::string &value)
|
|
||||||
{
|
|
||||||
mData = nullptr;
|
|
||||||
mType = VT_None;
|
|
||||||
setType(VT_String);
|
|
||||||
setString(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant::Variant(int value)
|
|
||||||
{
|
|
||||||
mData = nullptr;
|
|
||||||
mType = VT_None;
|
|
||||||
setType(VT_Long);
|
|
||||||
setInteger(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant::Variant(float value)
|
|
||||||
{
|
|
||||||
mData = nullptr;
|
|
||||||
mType = VT_None;
|
|
||||||
setType(VT_Float);
|
|
||||||
setFloat(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant::~Variant()
|
|
||||||
{
|
|
||||||
delete mData;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant& ESM::Variant::operator= (const Variant& variant)
|
|
||||||
{
|
|
||||||
if (&variant!=this)
|
|
||||||
{
|
{
|
||||||
VariantDataBase *newData = variant.mData ? variant.mData->clone() : nullptr;
|
T operator()(int value) const { return static_cast<T>(value); }
|
||||||
|
|
||||||
delete mData;
|
T operator()(float value) const { return static_cast<T>(value); }
|
||||||
|
|
||||||
mType = variant.mType;
|
template <typename V>
|
||||||
mData = newData;
|
T operator()(const V&) const
|
||||||
}
|
{
|
||||||
|
if constexpr (orDefault)
|
||||||
|
return T {};
|
||||||
|
else
|
||||||
|
throw std::runtime_error("cannot convert variant");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return *this;
|
template <typename T>
|
||||||
}
|
struct SetValue
|
||||||
|
|
||||||
ESM::Variant& ESM::Variant::operator= (Variant&& variant)
|
|
||||||
{
|
|
||||||
if (&variant!=this)
|
|
||||||
{
|
{
|
||||||
delete mData;
|
T mValue;
|
||||||
|
|
||||||
mType = variant.mType;
|
explicit SetValue(T value) : mValue(value) {}
|
||||||
mData = variant.mData;
|
|
||||||
|
|
||||||
variant.mData = nullptr;
|
void operator()(int& value) const { value = static_cast<int>(mValue); }
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
void operator()(float& value) const { value = static_cast<float>(mValue); }
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Variant::Variant (const Variant& variant)
|
template <typename V>
|
||||||
: mType (variant.mType), mData (variant.mData ? variant.mData->clone() : nullptr)
|
void operator()(V&) const { throw std::runtime_error("cannot convert variant"); }
|
||||||
{}
|
};
|
||||||
|
|
||||||
ESM::Variant::Variant(Variant&& variant)
|
|
||||||
: mType (variant.mType), mData (variant.mData)
|
|
||||||
{
|
|
||||||
variant.mData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::VarType ESM::Variant::getType() const
|
|
||||||
{
|
|
||||||
return mType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ESM::Variant::getString() const
|
std::string ESM::Variant::getString() const
|
||||||
{
|
{
|
||||||
if (!mData)
|
return std::get<std::string>(mData);
|
||||||
throw std::runtime_error ("can not convert empty variant to string");
|
|
||||||
|
|
||||||
return mData->getString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ESM::Variant::getInteger() const
|
int ESM::Variant::getInteger() const
|
||||||
{
|
{
|
||||||
if (!mData)
|
return std::visit(GetValue<int>{}, mData);
|
||||||
throw std::runtime_error ("can not convert empty variant to integer");
|
|
||||||
|
|
||||||
return mData->getInteger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float ESM::Variant::getFloat() const
|
float ESM::Variant::getFloat() const
|
||||||
{
|
{
|
||||||
if (!mData)
|
return std::visit(GetValue<float>{}, mData);
|
||||||
throw std::runtime_error ("can not convert empty variant to float");
|
|
||||||
|
|
||||||
return mData->getFloat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::read (ESMReader& esm, Format format)
|
void ESM::Variant::read (ESMReader& esm, Format format)
|
||||||
|
@ -202,9 +149,7 @@ void ESM::Variant::read (ESMReader& esm, Format format)
|
||||||
|
|
||||||
setType (type);
|
setType (type);
|
||||||
|
|
||||||
// data
|
std::visit(ReadESMVariantValue {esm, format, mType}, mData);
|
||||||
if (mData)
|
|
||||||
mData->read (esm, format, mType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::write (ESMWriter& esm, Format format) const
|
void ESM::Variant::write (ESMWriter& esm, Format format) const
|
||||||
|
@ -227,7 +172,7 @@ void ESM::Variant::write (ESMWriter& esm, Format format) const
|
||||||
// nothing to do here for GMST format
|
// nothing to do here for GMST format
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mData->write (esm, format, mType);
|
std::visit(WriteESMVariantValue {esm, format, mType}, mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::write (std::ostream& stream) const
|
void ESM::Variant::write (std::ostream& stream) const
|
||||||
|
@ -246,27 +191,27 @@ void ESM::Variant::write (std::ostream& stream) const
|
||||||
|
|
||||||
case VT_Short:
|
case VT_Short:
|
||||||
|
|
||||||
stream << "variant short: " << mData->getInteger();
|
stream << "variant short: " << std::get<int>(mData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_Int:
|
case VT_Int:
|
||||||
|
|
||||||
stream << "variant int: " << mData->getInteger();
|
stream << "variant int: " << std::get<int>(mData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_Long:
|
case VT_Long:
|
||||||
|
|
||||||
stream << "variant long: " << mData->getInteger();
|
stream << "variant long: " << std::get<int>(mData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_Float:
|
case VT_Float:
|
||||||
|
|
||||||
stream << "variant float: " << mData->getFloat();
|
stream << "variant float: " << std::get<float>(mData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_String:
|
case VT_String:
|
||||||
|
|
||||||
stream << "variant string: \"" << mData->getString() << "\"";
|
stream << "variant string: \"" << std::get<std::string>(mData) << "\"";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,74 +220,50 @@ void ESM::Variant::setType (VarType type)
|
||||||
{
|
{
|
||||||
if (type!=mType)
|
if (type!=mType)
|
||||||
{
|
{
|
||||||
VariantDataBase *newData = nullptr;
|
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case VT_Unknown:
|
case VT_Unknown:
|
||||||
case VT_None:
|
case VT_None:
|
||||||
|
mData = std::monostate {};
|
||||||
break; // no data
|
break;
|
||||||
|
|
||||||
case VT_Short:
|
case VT_Short:
|
||||||
case VT_Int:
|
case VT_Int:
|
||||||
case VT_Long:
|
case VT_Long:
|
||||||
|
mData = std::visit(GetValue<int, true>{}, mData);
|
||||||
newData = new VariantIntegerData (mData);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_Float:
|
case VT_Float:
|
||||||
|
mData = std::visit(GetValue<float, true>{}, mData);
|
||||||
newData = new VariantFloatData (mData);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_String:
|
case VT_String:
|
||||||
|
mData = std::string {};
|
||||||
newData = new VariantStringData (mData);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete mData;
|
|
||||||
mData = newData;
|
|
||||||
mType = type;
|
mType = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::setString (const std::string& value)
|
void ESM::Variant::setString (const std::string& value)
|
||||||
{
|
{
|
||||||
if (!mData)
|
std::get<std::string>(mData) = value;
|
||||||
throw std::runtime_error ("can not assign string to empty variant");
|
}
|
||||||
|
|
||||||
mData->setString (value);
|
void ESM::Variant::setString (std::string&& value)
|
||||||
|
{
|
||||||
|
std::get<std::string>(mData) = std::move(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::setInteger (int value)
|
void ESM::Variant::setInteger (int value)
|
||||||
{
|
{
|
||||||
if (!mData)
|
std::visit(SetValue(value), mData);
|
||||||
throw std::runtime_error ("can not assign integer to empty variant");
|
|
||||||
|
|
||||||
mData->setInteger (value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Variant::setFloat (float value)
|
void ESM::Variant::setFloat (float value)
|
||||||
{
|
{
|
||||||
if (!mData)
|
std::visit(SetValue(value), mData);
|
||||||
throw std::runtime_error ("can not assign float to empty variant");
|
|
||||||
|
|
||||||
mData->setFloat (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ESM::Variant::isEqual (const Variant& value) const
|
|
||||||
{
|
|
||||||
if (mType!=value.mType)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!mData)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
assert (value.mData);
|
|
||||||
|
|
||||||
return mData->isEqual (*value.mData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& ESM::operator<< (std::ostream& stream, const Variant& value)
|
std::ostream& ESM::operator<< (std::ostream& stream, const Variant& value)
|
||||||
|
@ -350,13 +271,3 @@ std::ostream& ESM::operator<< (std::ostream& stream, const Variant& value)
|
||||||
value.write (stream);
|
value.write (stream);
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESM::operator== (const Variant& left, const Variant& right)
|
|
||||||
{
|
|
||||||
return left.isEqual (right);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ESM::operator!= (const Variant& left, const Variant& right)
|
|
||||||
{
|
|
||||||
return !(left==right);
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <variant>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
@ -20,12 +22,10 @@ namespace ESM
|
||||||
VT_String
|
VT_String
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariantDataBase;
|
|
||||||
|
|
||||||
class Variant
|
class Variant
|
||||||
{
|
{
|
||||||
VarType mType;
|
VarType mType;
|
||||||
VariantDataBase *mData;
|
std::variant<std::monostate, int, float, std::string> mData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -37,21 +37,17 @@ namespace ESM
|
||||||
Format_Local // local script variables in save game files
|
Format_Local // local script variables in save game files
|
||||||
};
|
};
|
||||||
|
|
||||||
Variant();
|
Variant() : mType (VT_None), mData (std::monostate{}) {}
|
||||||
|
|
||||||
Variant (const std::string& value);
|
explicit Variant(const std::string& value) : mType(VT_String), mData(value) {}
|
||||||
Variant (int value);
|
|
||||||
Variant (float value);
|
|
||||||
|
|
||||||
~Variant();
|
explicit Variant(std::string&& value) : mType(VT_String), mData(std::move(value)) {}
|
||||||
|
|
||||||
Variant& operator= (const Variant& variant);
|
explicit Variant(int value) : mType(VT_Long), mData(value) {}
|
||||||
Variant& operator= (Variant && variant);
|
|
||||||
|
|
||||||
Variant (const Variant& variant);
|
explicit Variant(float value) : mType(VT_Float), mData(value) {}
|
||||||
Variant (Variant&& variant);
|
|
||||||
|
|
||||||
VarType getType() const;
|
VarType getType() const { return mType; }
|
||||||
|
|
||||||
std::string getString() const;
|
std::string getString() const;
|
||||||
///< Will throw an exception, if value can not be represented as a string.
|
///< Will throw an exception, if value can not be represented as a string.
|
||||||
|
@ -75,19 +71,27 @@ namespace ESM
|
||||||
void setString (const std::string& value);
|
void setString (const std::string& value);
|
||||||
///< Will throw an exception, if type is not compatible with string.
|
///< Will throw an exception, if type is not compatible with string.
|
||||||
|
|
||||||
|
void setString (std::string&& value);
|
||||||
|
///< Will throw an exception, if type is not compatible with string.
|
||||||
|
|
||||||
void setInteger (int value);
|
void setInteger (int value);
|
||||||
///< Will throw an exception, if type is not compatible with integer.
|
///< Will throw an exception, if type is not compatible with integer.
|
||||||
|
|
||||||
void setFloat (float value);
|
void setFloat (float value);
|
||||||
///< Will throw an exception, if type is not compatible with float.
|
///< Will throw an exception, if type is not compatible with float.
|
||||||
|
|
||||||
bool isEqual (const Variant& value) const;
|
friend bool operator==(const Variant& left, const Variant& right)
|
||||||
|
{
|
||||||
|
return std::tie(left.mType, left.mData) == std::tie(right.mType, right.mData);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const Variant& left, const Variant& right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, const Variant& value);
|
std::ostream& operator<<(std::ostream& stream, const Variant& value);
|
||||||
|
|
||||||
bool operator== (const Variant& left, const Variant& right);
|
|
||||||
bool operator!= (const Variant& left, const Variant& right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,71 +5,7 @@
|
||||||
#include "esmreader.hpp"
|
#include "esmreader.hpp"
|
||||||
#include "esmwriter.hpp"
|
#include "esmwriter.hpp"
|
||||||
|
|
||||||
ESM::VariantDataBase::~VariantDataBase() {}
|
void ESM::readESMVariantValue(ESMReader& esm, Variant::Format format, VarType type, std::string& out)
|
||||||
|
|
||||||
std::string ESM::VariantDataBase::getString (bool default_) const
|
|
||||||
{
|
|
||||||
if (default_)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
throw std::runtime_error ("can not convert variant to string");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ESM::VariantDataBase::getInteger (bool default_) const
|
|
||||||
{
|
|
||||||
if (default_)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
throw std::runtime_error ("can not convert variant to integer");
|
|
||||||
}
|
|
||||||
|
|
||||||
float ESM::VariantDataBase::getFloat (bool default_) const
|
|
||||||
{
|
|
||||||
if (default_)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
throw std::runtime_error ("can not convert variant to float");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantDataBase::setString (const std::string& value)
|
|
||||||
{
|
|
||||||
throw std::runtime_error ("conversion of string to variant not possible");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantDataBase::setInteger (int value)
|
|
||||||
{
|
|
||||||
throw std::runtime_error ("conversion of integer to variant not possible");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantDataBase::setFloat (float value)
|
|
||||||
{
|
|
||||||
throw std::runtime_error ("conversion of float to variant not possible");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ESM::VariantStringData::VariantStringData (const VariantDataBase *data)
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
mValue = data->getString (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::VariantDataBase *ESM::VariantStringData::clone() const
|
|
||||||
{
|
|
||||||
return new VariantStringData (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ESM::VariantStringData::getString (bool default_) const
|
|
||||||
{
|
|
||||||
return mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantStringData::setString (const std::string& value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarType type)
|
|
||||||
{
|
{
|
||||||
if (type!=VT_String)
|
if (type!=VT_String)
|
||||||
throw std::logic_error ("not a string type");
|
throw std::logic_error ("not a string type");
|
||||||
|
@ -84,10 +20,10 @@ void ESM::VariantStringData::read (ESMReader& esm, Variant::Format format, VarTy
|
||||||
esm.fail ("local variables of type string not supported");
|
esm.fail ("local variables of type string not supported");
|
||||||
|
|
||||||
// GMST
|
// GMST
|
||||||
mValue = esm.getHString();
|
out = esm.getHString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::VariantStringData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
void ESM::writeESMVariantValue(ESMWriter& esm, Variant::Format format, VarType type, const std::string& in)
|
||||||
{
|
{
|
||||||
if (type!=VT_String)
|
if (type!=VT_String)
|
||||||
throw std::logic_error ("not a string type");
|
throw std::logic_error ("not a string type");
|
||||||
|
@ -102,48 +38,10 @@ void ESM::VariantStringData::write (ESMWriter& esm, Variant::Format format, VarT
|
||||||
throw std::runtime_error ("local variables of type string not supported");
|
throw std::runtime_error ("local variables of type string not supported");
|
||||||
|
|
||||||
// GMST
|
// GMST
|
||||||
esm.writeHNString ("STRV", mValue);
|
esm.writeHNString("STRV", in);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESM::VariantStringData::isEqual (const VariantDataBase& value) const
|
void ESM::readESMVariantValue(ESMReader& esm, Variant::Format format, VarType type, int& out)
|
||||||
{
|
|
||||||
return dynamic_cast<const VariantStringData&> (value).mValue==mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ESM::VariantIntegerData::VariantIntegerData (const VariantDataBase *data) : mValue (0)
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
mValue = data->getInteger (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::VariantDataBase *ESM::VariantIntegerData::clone() const
|
|
||||||
{
|
|
||||||
return new VariantIntegerData (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ESM::VariantIntegerData::getInteger (bool default_) const
|
|
||||||
{
|
|
||||||
return mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
float ESM::VariantIntegerData::getFloat (bool default_) const
|
|
||||||
{
|
|
||||||
return static_cast<float>(mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantIntegerData::setInteger (int value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantIntegerData::setFloat (float value)
|
|
||||||
{
|
|
||||||
mValue = static_cast<int> (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarType type)
|
|
||||||
{
|
{
|
||||||
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
||||||
throw std::logic_error ("not an integer type");
|
throw std::logic_error ("not an integer type");
|
||||||
|
@ -156,12 +54,12 @@ void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarT
|
||||||
if (type==VT_Short)
|
if (type==VT_Short)
|
||||||
{
|
{
|
||||||
if (value!=value)
|
if (value!=value)
|
||||||
mValue = 0; // nan
|
out = 0; // nan
|
||||||
else
|
else
|
||||||
mValue = static_cast<short> (value);
|
out = static_cast<short> (value);
|
||||||
}
|
}
|
||||||
else if (type==VT_Long)
|
else if (type==VT_Long)
|
||||||
mValue = static_cast<int> (value);
|
out = static_cast<int> (value);
|
||||||
else
|
else
|
||||||
esm.fail ("unsupported global variable integer type");
|
esm.fail ("unsupported global variable integer type");
|
||||||
}
|
}
|
||||||
|
@ -176,7 +74,7 @@ void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarT
|
||||||
esm.fail (stream.str());
|
esm.fail (stream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.getHT (mValue);
|
esm.getHT(out);
|
||||||
}
|
}
|
||||||
else if (format==Variant::Format_Local)
|
else if (format==Variant::Format_Local)
|
||||||
{
|
{
|
||||||
|
@ -184,18 +82,18 @@ void ESM::VariantIntegerData::read (ESMReader& esm, Variant::Format format, VarT
|
||||||
{
|
{
|
||||||
short value;
|
short value;
|
||||||
esm.getHT(value);
|
esm.getHT(value);
|
||||||
mValue = value;
|
out = value;
|
||||||
}
|
}
|
||||||
else if (type==VT_Int)
|
else if (type==VT_Int)
|
||||||
{
|
{
|
||||||
esm.getHT(mValue);
|
esm.getHT(out);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
esm.fail("unsupported local variable integer type");
|
esm.fail("unsupported local variable integer type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
void ESM::writeESMVariantValue(ESMWriter& esm, Variant::Format format, VarType type, int in)
|
||||||
{
|
{
|
||||||
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
if (type!=VT_Short && type!=VT_Long && type!=VT_Int)
|
||||||
throw std::logic_error ("not an integer type");
|
throw std::logic_error ("not an integer type");
|
||||||
|
@ -204,7 +102,7 @@ void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, Var
|
||||||
{
|
{
|
||||||
if (type==VT_Short || type==VT_Long)
|
if (type==VT_Short || type==VT_Long)
|
||||||
{
|
{
|
||||||
float value = static_cast<float>(mValue);
|
float value = static_cast<float>(in);
|
||||||
esm.writeHNString ("FNAM", type==VT_Short ? "s" : "l");
|
esm.writeHNString ("FNAM", type==VT_Short ? "s" : "l");
|
||||||
esm.writeHNT ("FLTV", value);
|
esm.writeHNT ("FLTV", value);
|
||||||
}
|
}
|
||||||
|
@ -222,72 +120,35 @@ void ESM::VariantIntegerData::write (ESMWriter& esm, Variant::Format format, Var
|
||||||
throw std::runtime_error (stream.str());
|
throw std::runtime_error (stream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.writeHNT ("INTV", mValue);
|
esm.writeHNT("INTV", in);
|
||||||
}
|
}
|
||||||
else if (format==Variant::Format_Local)
|
else if (format==Variant::Format_Local)
|
||||||
{
|
{
|
||||||
if (type==VT_Short)
|
if (type==VT_Short)
|
||||||
esm.writeHNT ("STTV", (short)mValue);
|
esm.writeHNT("STTV", static_cast<short>(in));
|
||||||
else if (type == VT_Int)
|
else if (type == VT_Int)
|
||||||
esm.writeHNT ("INTV", mValue);
|
esm.writeHNT("INTV", in);
|
||||||
else
|
else
|
||||||
throw std::runtime_error("unsupported local variable integer type");
|
throw std::runtime_error("unsupported local variable integer type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESM::VariantIntegerData::isEqual (const VariantDataBase& value) const
|
void ESM::readESMVariantValue(ESMReader& esm, Variant::Format format, VarType type, float& out)
|
||||||
{
|
|
||||||
return dynamic_cast<const VariantIntegerData&> (value).mValue==mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ESM::VariantFloatData::VariantFloatData (const VariantDataBase *data) : mValue (0)
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
mValue = data->getFloat (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::VariantDataBase *ESM::VariantFloatData::clone() const
|
|
||||||
{
|
|
||||||
return new VariantFloatData (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ESM::VariantFloatData::getInteger (bool default_) const
|
|
||||||
{
|
|
||||||
return static_cast<int> (mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
float ESM::VariantFloatData::getFloat (bool default_) const
|
|
||||||
{
|
|
||||||
return mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantFloatData::setInteger (int value)
|
|
||||||
{
|
|
||||||
mValue = static_cast<float>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantFloatData::setFloat (float value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESM::VariantFloatData::read (ESMReader& esm, Variant::Format format, VarType type)
|
|
||||||
{
|
{
|
||||||
if (type!=VT_Float)
|
if (type!=VT_Float)
|
||||||
throw std::logic_error ("not a float type");
|
throw std::logic_error ("not a float type");
|
||||||
|
|
||||||
if (format==Variant::Format_Global)
|
if (format==Variant::Format_Global)
|
||||||
{
|
{
|
||||||
esm.getHNT (mValue, "FLTV");
|
esm.getHNT(out, "FLTV");
|
||||||
}
|
}
|
||||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info || format==Variant::Format_Local)
|
else if (format==Variant::Format_Gmst || format==Variant::Format_Info || format==Variant::Format_Local)
|
||||||
{
|
{
|
||||||
esm.getHT (mValue);
|
esm.getHT(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::VariantFloatData::write (ESMWriter& esm, Variant::Format format, VarType type) const
|
void ESM::writeESMVariantValue(ESMWriter& esm, Variant::Format format, VarType type, float in)
|
||||||
{
|
{
|
||||||
if (type!=VT_Float)
|
if (type!=VT_Float)
|
||||||
throw std::logic_error ("not a float type");
|
throw std::logic_error ("not a float type");
|
||||||
|
@ -295,15 +156,10 @@ void ESM::VariantFloatData::write (ESMWriter& esm, Variant::Format format, VarTy
|
||||||
if (format==Variant::Format_Global)
|
if (format==Variant::Format_Global)
|
||||||
{
|
{
|
||||||
esm.writeHNString ("FNAM", "f");
|
esm.writeHNString ("FNAM", "f");
|
||||||
esm.writeHNT ("FLTV", mValue);
|
esm.writeHNT("FLTV", in);
|
||||||
}
|
}
|
||||||
else if (format==Variant::Format_Gmst || format==Variant::Format_Info || format==Variant::Format_Local)
|
else if (format==Variant::Format_Gmst || format==Variant::Format_Info || format==Variant::Format_Local)
|
||||||
{
|
{
|
||||||
esm.writeHNT ("FLTV", mValue);
|
esm.writeHNT("FLTV", in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ESM::VariantFloatData::isEqual (const VariantDataBase& value) const
|
|
||||||
{
|
|
||||||
return dynamic_cast<const VariantFloatData&> (value).mValue==mValue;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,177 +2,58 @@
|
||||||
#define OPENMW_ESM_VARIANTIMP_H
|
#define OPENMW_ESM_VARIANTIMP_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "variant.hpp"
|
#include "variant.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
class VariantDataBase
|
void readESMVariantValue(ESMReader& reader, Variant::Format format, VarType type, std::string& value);
|
||||||
|
|
||||||
|
void readESMVariantValue(ESMReader& reader, Variant::Format format, VarType type, float& value);
|
||||||
|
|
||||||
|
void readESMVariantValue(ESMReader& reader, Variant::Format format, VarType type, int& value);
|
||||||
|
|
||||||
|
void writeESMVariantValue(ESMWriter& writer, Variant::Format format, VarType type, const std::string& value);
|
||||||
|
|
||||||
|
void writeESMVariantValue(ESMWriter& writer, Variant::Format format, VarType type, float value);
|
||||||
|
|
||||||
|
void writeESMVariantValue(ESMWriter& writer, Variant::Format format, VarType type, int value);
|
||||||
|
|
||||||
|
struct ReadESMVariantValue
|
||||||
{
|
{
|
||||||
public:
|
std::reference_wrapper<ESMReader> mReader;
|
||||||
|
Variant::Format mFormat;
|
||||||
|
VarType mType;
|
||||||
|
|
||||||
virtual ~VariantDataBase();
|
ReadESMVariantValue(ESMReader& reader, Variant::Format format, VarType type)
|
||||||
|
: mReader(reader), mFormat(format), mType(type) {}
|
||||||
|
|
||||||
virtual VariantDataBase *clone() const = 0;
|
void operator()(std::monostate) const {}
|
||||||
|
|
||||||
virtual std::string getString (bool default_ = false) const;
|
|
||||||
///< Will throw an exception, if value can not be represented as a string.
|
|
||||||
///
|
|
||||||
/// \note Numeric values are not converted to strings.
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual int getInteger (bool default_ = false) const;
|
|
||||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
|
||||||
/// casting of float values is permitted).
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual float getFloat (bool default_ = false) const;
|
|
||||||
///< Will throw an exception, if value can not be represented as a float value.
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual void setString (const std::string& value);
|
|
||||||
///< Will throw an exception, if type is not compatible with string.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual void setInteger (int value);
|
|
||||||
///< Will throw an exception, if type is not compatible with integer.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual void setFloat (float value);
|
|
||||||
///< Will throw an exception, if type is not compatible with float.
|
|
||||||
///
|
|
||||||
/// Default-implementation: throw an exception.
|
|
||||||
|
|
||||||
virtual void read (ESMReader& esm, Variant::Format format, VarType type) = 0;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
|
||||||
|
|
||||||
virtual void write (ESMWriter& esm, Variant::Format format, VarType type) const = 0;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown.
|
|
||||||
|
|
||||||
virtual bool isEqual (const VariantDataBase& value) const = 0;
|
|
||||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator()(T& value) const
|
||||||
|
{
|
||||||
|
readESMVariantValue(mReader.get(), mFormat, mType, value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariantStringData : public VariantDataBase
|
struct WriteESMVariantValue
|
||||||
{
|
{
|
||||||
std::string mValue;
|
std::reference_wrapper<ESMWriter> mWriter;
|
||||||
|
Variant::Format mFormat;
|
||||||
|
VarType mType;
|
||||||
|
|
||||||
public:
|
WriteESMVariantValue(ESMWriter& writer, Variant::Format format, VarType type)
|
||||||
|
: mWriter(writer), mFormat(format), mType(type) {}
|
||||||
|
|
||||||
VariantStringData (const VariantDataBase *data = nullptr);
|
void operator()(std::monostate) const {}
|
||||||
///< Calling the constructor with an incompatible data type will result in a silent
|
|
||||||
/// default initialisation.
|
|
||||||
|
|
||||||
VariantDataBase *clone() const override;
|
template <typename T>
|
||||||
|
void operator()(const T& value) const
|
||||||
std::string getString (bool default_ = false) const override;
|
{
|
||||||
///< Will throw an exception, if value can not be represented as a string.
|
writeESMVariantValue(mWriter.get(), mFormat, mType, value);
|
||||||
///
|
}
|
||||||
/// \note Numeric values are not converted to strings.
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
|
|
||||||
void setString (const std::string& value) override;
|
|
||||||
///< Will throw an exception, if type is not compatible with string.
|
|
||||||
|
|
||||||
void read (ESMReader& esm, Variant::Format format, VarType type) override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
|
||||||
|
|
||||||
void write (ESMWriter& esm, Variant::Format format, VarType type) const override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown.
|
|
||||||
|
|
||||||
bool isEqual (const VariantDataBase& value) const override;
|
|
||||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
|
||||||
};
|
|
||||||
|
|
||||||
class VariantIntegerData : public VariantDataBase
|
|
||||||
{
|
|
||||||
int mValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
VariantIntegerData (const VariantDataBase *data = nullptr);
|
|
||||||
///< Calling the constructor with an incompatible data type will result in a silent
|
|
||||||
/// default initialisation.
|
|
||||||
|
|
||||||
VariantDataBase *clone() const override;
|
|
||||||
|
|
||||||
int getInteger (bool default_ = false) const override;
|
|
||||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
|
||||||
/// casting of float values is permitted).
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
|
|
||||||
float getFloat (bool default_ = false) const override;
|
|
||||||
///< Will throw an exception, if value can not be represented as a float value.
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
|
|
||||||
void setInteger (int value) override;
|
|
||||||
///< Will throw an exception, if type is not compatible with integer.
|
|
||||||
|
|
||||||
void setFloat (float value) override;
|
|
||||||
///< Will throw an exception, if type is not compatible with float.
|
|
||||||
|
|
||||||
void read (ESMReader& esm, Variant::Format format, VarType type) override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
|
||||||
|
|
||||||
void write (ESMWriter& esm, Variant::Format format, VarType type) const override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown.
|
|
||||||
|
|
||||||
bool isEqual (const VariantDataBase& value) const override;
|
|
||||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
|
||||||
};
|
|
||||||
|
|
||||||
class VariantFloatData : public VariantDataBase
|
|
||||||
{
|
|
||||||
float mValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
VariantFloatData (const VariantDataBase *data = nullptr);
|
|
||||||
///< Calling the constructor with an incompatible data type will result in a silent
|
|
||||||
/// default initialisation.
|
|
||||||
|
|
||||||
VariantDataBase *clone() const override;
|
|
||||||
|
|
||||||
int getInteger (bool default_ = false) const override;
|
|
||||||
///< Will throw an exception, if value can not be represented as an integer (implicit
|
|
||||||
/// casting of float values is permitted).
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
|
|
||||||
float getFloat (bool default_ = false) const override;
|
|
||||||
///< Will throw an exception, if value can not be represented as a float value.
|
|
||||||
///
|
|
||||||
/// \param default_ Return a default value instead of throwing an exception.
|
|
||||||
|
|
||||||
void setInteger (int value) override;
|
|
||||||
///< Will throw an exception, if type is not compatible with integer.
|
|
||||||
|
|
||||||
void setFloat (float value) override;
|
|
||||||
///< Will throw an exception, if type is not compatible with float.
|
|
||||||
|
|
||||||
void read (ESMReader& esm, Variant::Format format, VarType type) override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown via ESMReader::fail
|
|
||||||
|
|
||||||
void write (ESMWriter& esm, Variant::Format format, VarType type) const override;
|
|
||||||
///< If \a type is not supported by \a format, an exception is thrown.
|
|
||||||
|
|
||||||
bool isEqual (const VariantDataBase& value) const override;
|
|
||||||
///< If the (C++) type of \a value does not match the type of *this, an exception is thrown.
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue