diff --git a/Framework/Core/include/Framework/Variant.h b/Framework/Core/include/Framework/Variant.h index e69ca05b91d98..7121c5fad0669 100644 --- a/Framework/Core/include/Framework/Variant.h +++ b/Framework/Core/include/Framework/Variant.h @@ -274,13 +274,24 @@ struct variant_helper> { // Allocates a new store and copies into it. static void set(void* store, std::vector value) { - new (reinterpret_cast*>(store)) std::vector{}; - *(reinterpret_cast*>(store)) = value; + auto ptr = reinterpret_cast*>(store); + new (ptr) std::vector{value}; } static std::vector const& get(const void* store) { return *(reinterpret_cast const*>(store)); } }; +template <> +struct variant_helper { + static void set(void* store, std::string* values, size_t size) + { + auto ptr = reinterpret_cast*>(store); + new (ptr) std::vector{values, values + size}; + } + + static std::string const* get(const void* store) { return (*(reinterpret_cast const*>(store))).data(); } +}; + template <> struct variant_helper { static const char* get(const void* store) { return *reinterpret_cast(store); } @@ -360,6 +371,16 @@ class Variant return variant_helper::get(&mStore); } + template + [[nodiscard]] std::string const* get() const + requires(std::same_as) + { + if (mType != VariantType::ArrayString) { + throw runtime_error_f("Variant::get: Mismatch between types %d %d.", mType, VariantType::ArrayString); + } + return variant_helper::get(&mStore); + } + template void set(T value) { diff --git a/Framework/Core/include/Framework/VariantPropertyTreeHelpers.h b/Framework/Core/include/Framework/VariantPropertyTreeHelpers.h index a51e3e03ffc5e..05ab71d39b0e4 100644 --- a/Framework/Core/include/Framework/VariantPropertyTreeHelpers.h +++ b/Framework/Core/include/Framework/VariantPropertyTreeHelpers.h @@ -36,7 +36,7 @@ boost::property_tree::ptree basicVectorToBranch(std::vector&& values) } template -boost::property_tree::ptree vectorToBranch(T* values, size_t size) +boost::property_tree::ptree vectorToBranch(T const* values, size_t size) { boost::property_tree::ptree branch; branch.put_child("values", basicVectorToBranch(values, size)); @@ -150,17 +150,17 @@ extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(f extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(int*, size_t); extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(double*, size_t); extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(bool*, size_t); -extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(std::basic_string*, size_t); +extern template boost::property_tree::ptree o2::framework::basicVectorToBranch(std::basic_string const*, size_t); extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); -extern template boost::property_tree::ptree o2::framework::vectorToBranch(float*, size_t); -extern template boost::property_tree::ptree o2::framework::vectorToBranch(int*, size_t); -extern template boost::property_tree::ptree o2::framework::vectorToBranch(double*, size_t); -extern template boost::property_tree::ptree o2::framework::vectorToBranch(bool*, size_t); -extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::basic_string*, size_t); +extern template boost::property_tree::ptree o2::framework::vectorToBranch(float const*, size_t); +extern template boost::property_tree::ptree o2::framework::vectorToBranch(int const*, size_t); +extern template boost::property_tree::ptree o2::framework::vectorToBranch(double const*, size_t); +extern template boost::property_tree::ptree o2::framework::vectorToBranch(bool const*, size_t); +extern template boost::property_tree::ptree o2::framework::vectorToBranch(std::basic_string const*, size_t); extern template boost::property_tree::ptree o2::framework::labeledArrayToBranch(o2::framework::LabeledArray&& array); extern template boost::property_tree::ptree o2::framework::labeledArrayToBranch(o2::framework::LabeledArray&& array); diff --git a/Framework/Core/src/Variant.cxx b/Framework/Core/src/Variant.cxx index 21eb6103aa56a..e54a973bd4413 100644 --- a/Framework/Core/src/Variant.cxx +++ b/Framework/Core/src/Variant.cxx @@ -89,29 +89,29 @@ Variant::Variant(const Variant& other) : mType(other.mType) // In case this is an array we need to duplicate it to avoid // double deletion. switch (mType) { - case variant_trait_v: + case VariantType::String: mSize = other.mSize; variant_helper::set(&mStore, other.get()); return; - case variant_trait_v: + case VariantType::ArrayInt: mSize = other.mSize; variant_helper::set(&mStore, other.get(), mSize); return; - case variant_trait_v: + case VariantType::ArrayFloat: mSize = other.mSize; variant_helper::set(&mStore, other.get(), mSize); return; - case variant_trait_v: + case VariantType::ArrayDouble: mSize = other.mSize; variant_helper::set(&mStore, other.get(), mSize); return; - case variant_trait_v: + case VariantType::ArrayBool: mSize = other.mSize; variant_helper::set(&mStore, other.get(), mSize); return; - case variant_trait_v: + case VariantType::ArrayString: mSize = other.mSize; - variant_helper::set(&mStore, other.get(), mSize); + variant_helper>::set(&mStore, other.get>()); return; default: mStore = other.mStore; @@ -124,23 +124,14 @@ Variant::Variant(Variant&& other) noexcept : mType(other.mType) mStore = other.mStore; mSize = other.mSize; switch (mType) { - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; - return; - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; - return; - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; - return; - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; - return; - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; + case VariantType::String: + case VariantType::ArrayInt: + case VariantType::ArrayFloat: + case VariantType::ArrayDouble: + case VariantType::ArrayBool: + case VariantType::ArrayString: + *reinterpret_cast(&(other.mStore)) = nullptr; return; - case variant_trait_v: - *reinterpret_cast(&(other.mStore)) = nullptr; default: return; } @@ -151,16 +142,20 @@ Variant::~Variant() // In case we allocated an array, we // should delete it. switch (mType) { - case variant_trait_v: - case variant_trait_v: - case variant_trait_v: - case variant_trait_v: - case variant_trait_v: - case variant_trait_v: + case VariantType::String: + case VariantType::ArrayInt: + case VariantType::ArrayFloat: + case VariantType::ArrayDouble: + case VariantType::ArrayBool: { if (reinterpret_cast(&mStore) != nullptr) { free(*reinterpret_cast(&mStore)); } return; + } + case VariantType::ArrayString: { + // Allocated with placement new. Nothing to delete. + return; + } default: return; } @@ -171,23 +166,23 @@ Variant& Variant::operator=(const Variant& other) mSize = other.mSize; mType = other.mType; switch (mType) { - case variant_trait_v: + case VariantType::String: variant_helper::set(&mStore, other.get()); return *this; - case variant_trait_v: + case VariantType::ArrayInt: variant_helper::set(&mStore, other.get(), mSize); return *this; - case variant_trait_v: + case VariantType::ArrayFloat: variant_helper::set(&mStore, other.get(), mSize); return *this; - case variant_trait_v: + case VariantType::ArrayDouble: variant_helper::set(&mStore, other.get(), mSize); return *this; - case variant_trait_v: + case VariantType::ArrayBool: variant_helper::set(&mStore, other.get(), mSize); return *this; - case variant_trait_v: - variant_helper::set(&mStore, other.get(), mSize); + case VariantType::ArrayString: + variant_helper>::set(&mStore, other.get>()); return *this; default: mStore = other.mStore; @@ -200,29 +195,29 @@ Variant& Variant::operator=(Variant&& other) noexcept mSize = other.mSize; mType = other.mType; switch (mType) { - case variant_trait_v: + case VariantType::String: variant_helper::set(&mStore, other.get()); *reinterpret_cast(&(other.mStore)) = nullptr; return *this; - case variant_trait_v: + case VariantType::ArrayInt: variant_helper::set(&mStore, other.get(), mSize); *reinterpret_cast(&(other.mStore)) = nullptr; return *this; - case variant_trait_v: + case VariantType::ArrayFloat: variant_helper::set(&mStore, other.get(), mSize); *reinterpret_cast(&(other.mStore)) = nullptr; return *this; - case variant_trait_v: + case VariantType::ArrayDouble: variant_helper::set(&mStore, other.get(), mSize); *reinterpret_cast(&(other.mStore)) = nullptr; return *this; - case variant_trait_v: + case VariantType::ArrayBool: variant_helper::set(&mStore, other.get(), mSize); *reinterpret_cast(&(other.mStore)) = nullptr; return *this; - case variant_trait_v: - variant_helper::set(&mStore, other.get(), mSize); - *reinterpret_cast(&(other.mStore)) = nullptr; + case VariantType::ArrayString: + variant_helper>::set(&mStore, other.get>()); + *reinterpret_cast**>(&(other.mStore)) = nullptr; return *this; default: mStore = other.mStore; diff --git a/Framework/Core/src/VariantPropertyTreeHelpers.cxx b/Framework/Core/src/VariantPropertyTreeHelpers.cxx index 2b1746aae2c66..cb0aefaab39ec 100644 --- a/Framework/Core/src/VariantPropertyTreeHelpers.cxx +++ b/Framework/Core/src/VariantPropertyTreeHelpers.cxx @@ -19,17 +19,17 @@ template boost::property_tree::ptree o2::framework::basicVectorToBranch(float*, template boost::property_tree::ptree o2::framework::basicVectorToBranch(int*, size_t); template boost::property_tree::ptree o2::framework::basicVectorToBranch(double*, size_t); template boost::property_tree::ptree o2::framework::basicVectorToBranch(bool*, size_t); -template boost::property_tree::ptree o2::framework::basicVectorToBranch(std::basic_string*, size_t); +template boost::property_tree::ptree o2::framework::basicVectorToBranch(std::basic_string const*, size_t); template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); template boost::property_tree::ptree o2::framework::vectorToBranch(std::vector&& values); -template boost::property_tree::ptree o2::framework::vectorToBranch(float*, size_t); -template boost::property_tree::ptree o2::framework::vectorToBranch(int*, size_t); -template boost::property_tree::ptree o2::framework::vectorToBranch(double*, size_t); -template boost::property_tree::ptree o2::framework::vectorToBranch(bool*, size_t); -template boost::property_tree::ptree o2::framework::vectorToBranch(std::basic_string*, size_t); +template boost::property_tree::ptree o2::framework::vectorToBranch(float const*, size_t); +template boost::property_tree::ptree o2::framework::vectorToBranch(int const*, size_t); +template boost::property_tree::ptree o2::framework::vectorToBranch(double const*, size_t); +template boost::property_tree::ptree o2::framework::vectorToBranch(bool const*, size_t); +template boost::property_tree::ptree o2::framework::vectorToBranch(std::basic_string const*, size_t); template boost::property_tree::ptree o2::framework::labeledArrayToBranch(o2::framework::LabeledArray&& array); template boost::property_tree::ptree o2::framework::labeledArrayToBranch(o2::framework::LabeledArray&& array);