Skip to content

Commit

Permalink
Merge pull request #402 from sandialabs/property_as_variant
Browse files Browse the repository at this point in the history
IOSS: Make Ioss_Property.h use variant instead of union
  • Loading branch information
gsjaardema authored Sep 18, 2023
2 parents 0f56703 + 788f39e commit d282d06
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 100 deletions.
136 changes: 51 additions & 85 deletions packages/seacas/libraries/ioss/src/Ioss_Property.C
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ namespace {
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, int value, Origin origin)
: name_(std::move(name)), type_(INTEGER), origin_(origin)
: name_(std::move(name)), type_(INTEGER), origin_(origin), data_(static_cast<int64_t>(value))
{
data_.ival = value;
}

/** \brief Create an INTEGER type property using an int64_t variable.
Expand All @@ -57,9 +56,8 @@ Ioss::Property::Property(std::string name, int value, Origin origin)
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, int64_t value, Origin origin)
: name_(std::move(name)), type_(INTEGER), origin_(origin)
: name_(std::move(name)), type_(INTEGER), origin_(origin), data_(value)
{
data_.ival = value;
}

/** \brief Create a REAL type property.
Expand All @@ -69,9 +67,8 @@ Ioss::Property::Property(std::string name, int64_t value, Origin origin)
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, double value, Origin origin)
: name_(std::move(name)), type_(REAL), origin_(origin)
: name_(std::move(name)), type_(REAL), origin_(origin), data_(value)
{
data_.rval = value;
}

/** \brief Create a STRING type property.
Expand All @@ -81,9 +78,8 @@ Ioss::Property::Property(std::string name, double value, Origin origin)
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, const std::string &value, Origin origin)
: name_(std::move(name)), type_(STRING), origin_(origin)
: name_(std::move(name)), type_(STRING), origin_(origin), data_(value)
{
data_.sval = new std::string(value);
}

/** \brief Create a VEC_INTEGER type property.
Expand All @@ -93,9 +89,8 @@ Ioss::Property::Property(std::string name, const std::string &value, Origin orig
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, const std::vector<int> &value, Origin origin)
: name_(std::move(name)), type_(VEC_INTEGER), origin_(origin)
: name_(std::move(name)), type_(VEC_INTEGER), origin_(origin), data_(value)
{
data_.ivec = new std::vector<int>(value);
}

/** \brief Create a VEC_DOUBLE type property.
Expand All @@ -105,9 +100,8 @@ Ioss::Property::Property(std::string name, const std::vector<int> &value, Origin
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, const std::vector<double> &value, Origin origin)
: name_(std::move(name)), type_(VEC_DOUBLE), origin_(origin)
: name_(std::move(name)), type_(VEC_DOUBLE), origin_(origin), data_(value)
{
data_.dvec = new std::vector<double>(value);
}

/** \brief Create a STRING type property from const char* argument.
Expand All @@ -117,9 +111,8 @@ Ioss::Property::Property(std::string name, const std::vector<double> &value, Ori
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, const char *value, Origin origin)
: name_(std::move(name)), type_(STRING), origin_(origin)
: name_(std::move(name)), type_(STRING), origin_(origin), data_(std::string(value))
{
data_.sval = new std::string(value);
}

/** \brief Create a POINTER type property.
Expand All @@ -129,9 +122,8 @@ Ioss::Property::Property(std::string name, const char *value, Origin origin)
* \param[in] origin The origin of the property - IMPLICIT, or EXTERNAL, or ATTRIBUTE
*/
Ioss::Property::Property(std::string name, void *value, Origin origin)
: name_(std::move(name)), type_(POINTER), origin_(origin)
: name_(std::move(name)), type_(POINTER), origin_(origin), data_(value)
{
data_.pval = value;
}

/** \brief Set implicit property with a specified type.
Expand All @@ -143,50 +135,7 @@ Ioss::Property::Property(std::string name, void *value, Origin origin)
Ioss::Property::Property(const Ioss::GroupingEntity *ge, std::string name, const BasicType type)
: name_(std::move(name)), type_(type), origin_(IMPLICIT)
{
data_.ge = ge;
}

/** \brief Copy constructor.
*
* \param[in] from The Ioss::Property to copy
*/
Ioss::Property::Property(const Ioss::Property &from)
: name_(from.name_), type_(from.type_), origin_(from.origin_)
{
if (!is_implicit() && type_ == STRING) {
data_.sval = new std::string(*(from.data_.sval));
}
else if (!is_implicit() && type_ == VEC_DOUBLE) {
data_.dvec = new std::vector<double>(*(from.data_.dvec));
}
else if (!is_implicit() && type_ == VEC_INTEGER) {
data_.ivec = new std::vector<int>(*(from.data_.ivec));
}
else {
data_ = from.data_;
}
}

Ioss::Property::~Property()
{
if (!is_implicit() && type_ == STRING) {
delete data_.sval;
}
else if (!is_implicit() && type_ == VEC_DOUBLE) {
delete data_.dvec;
}
else if (!is_implicit() && type_ == VEC_INTEGER) {
delete data_.ivec;
}
}

Ioss::Property &Ioss::Property::operator=(Ioss::Property rhs)
{
std::swap(this->name_, rhs.name_);
std::swap(this->type_, rhs.type_);
std::swap(this->origin_, rhs.origin_);
std::swap(this->data_, rhs.data_);
return *this;
data_ = ge;
}

bool Ioss::Property::operator==(const Ioss::Property &rhs) const
Expand All @@ -199,6 +148,10 @@ bool Ioss::Property::operator==(const Ioss::Property &rhs) const
return false;
}

if (this->origin_ != rhs.origin_) {
return false;
}

switch (this->type_) {
case INVALID: break;
case REAL:
Expand Down Expand Up @@ -248,7 +201,6 @@ bool Ioss::Property::operator==(const Ioss::Property &rhs) const
}
break;
}

return true;
}

Expand Down Expand Up @@ -342,12 +294,14 @@ bool Ioss::Property::get_value(int64_t *value) const
{
bool valid_request = type_ == INTEGER;
if (is_explicit()) {
*value = data_.ival;
assert(std::holds_alternative<int64_t>(data_));
*value = std::get<int64_t>(data_);
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
Expand All @@ -356,12 +310,14 @@ bool Ioss::Property::get_value(double *value) const
{
bool valid_request = type_ == REAL;
if (is_explicit()) {
*value = data_.rval;
assert(std::holds_alternative<double>(data_));
*value = std::get<double>(data_);
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
Expand All @@ -370,12 +326,14 @@ bool Ioss::Property::get_value(std::string *value) const
{
bool valid_request = type_ == STRING;
if (is_explicit()) {
*value = *(data_.sval);
assert(std::holds_alternative<std::string>(data_));
*value = std::get<std::string>(data_);
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
Expand All @@ -384,12 +342,15 @@ bool Ioss::Property::get_value(std::vector<int> *value) const
{
bool valid_request = type_ == VEC_INTEGER;
if (is_explicit()) {
std::copy(data_.ivec->begin(), data_.ivec->end(), std::back_inserter(*value));
assert(std::holds_alternative<std::vector<int>>(data_));
auto ivec = std::get<std::vector<int>>(data_);
std::copy(ivec.begin(), ivec.end(), std::back_inserter(*value));
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
Expand All @@ -398,12 +359,15 @@ bool Ioss::Property::get_value(std::vector<double> *value) const
{
bool valid_request = type_ == VEC_DOUBLE;
if (is_explicit()) {
std::copy(data_.dvec->begin(), data_.dvec->end(), std::back_inserter(*value));
assert(std::holds_alternative<std::vector<double>>(data_));
auto dvec = std::get<std::vector<double>>(data_);
std::copy(dvec.begin(), dvec.end(), std::back_inserter(*value));
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
Expand All @@ -412,12 +376,14 @@ bool Ioss::Property::get_value(void *&value) const
{
bool valid_request = type_ == POINTER;
if (is_explicit()) {
value = data_.pval;
assert(std::holds_alternative<void *>(data_));
value = std::get<void *>(data_);
}
else {
const Ioss::GroupingEntity *ge = data_.ge;
const Ioss::Property implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
assert(std::holds_alternative<const Ioss::GroupingEntity *>(data_));
const auto *ge = std::get<const Ioss::GroupingEntity *>(data_);
const auto implicit = ge->get_implicit_property(name_);
valid_request = implicit.get_value(value);
}
return valid_request;
}
31 changes: 17 additions & 14 deletions packages/seacas/libraries/ioss/src/Ioss_Property.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright(C) 1999-2022 National Technology & Engineering Solutions
// Copyright(C) 1999-2023 National Technology & Engineering Solutions
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
// NTESS, the U.S. Government retains certain rights in this software.
//
Expand All @@ -10,6 +10,7 @@

#include <cstdint> // for int64_t
#include <string> // for string
#include <variant>
#include <vector>

namespace Ioss {
Expand Down Expand Up @@ -46,10 +47,10 @@ namespace Ioss {
// To set implicit property
Property(const GroupingEntity *ge, std::string name, BasicType type);

Property(const Property &from);
Property &operator=(Property rhs);
Property(const Property &from) = default;
Property &operator=(Property &rhs);

~Property();
~Property() = default;

std::string get_string() const;
int64_t get_int() const;
Expand Down Expand Up @@ -101,6 +102,15 @@ namespace Ioss {
bool operator!=(const Ioss::Property &rhs) const;
bool operator==(const Ioss::Property &rhs) const;

friend void swap(Ioss::Property &first, Ioss::Property &second) // nothrow
{
using std::swap;
swap(first.name_, second.name_);
swap(first.type_, second.type_);
swap(first.origin_, second.origin_);
swap(first.data_, second.data_);
}

private:
std::string name_{};
BasicType type_{INVALID};
Expand All @@ -118,15 +128,8 @@ namespace Ioss {

/// The actual value of the property. Use 'type_' to
/// discriminate the actual type of the property.
union Data {
std::string *sval;
void *pval{nullptr};
const GroupingEntity *ge;
double rval;
int64_t ival;
std::vector<double> *dvec;
std::vector<int> *ivec;
};
Data data_{};
std::variant<std::string, const Ioss::GroupingEntity *, double, int64_t, std::vector<double>,
std::vector<int>, void *>
data_;
};
} // namespace Ioss
2 changes: 1 addition & 1 deletion packages/seacas/libraries/ioss/src/Ioss_PropertyManager.C
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void Ioss::PropertyManager::add(const Ioss::Property &new_prop)
if (iter != m_properties.end()) {
m_properties.erase(iter);
}
m_properties.insert(ValuePair(new_prop.get_name(), new_prop));
m_properties.emplace(new_prop.get_name(), new_prop);
}

/** \brief Checks if a property exists in the database.
Expand Down

0 comments on commit d282d06

Please sign in to comment.