From 26d097b16037c680e1d96b3395c9f1b614d4fd5f Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 15 Jan 2026 15:53:21 +0100 Subject: [PATCH 1/2] fix the issues on hardening Signed-off-by: Martijn Govers --- .../include/power_grid_model_c/basics.h | 2 - .../power_grid_model_c/src/buffer.cpp | 12 ++-- .../power_grid_model_c/src/dataset.cpp | 50 ++++++++++--- .../src/forward_declarations.hpp | 41 ++++++++--- .../power_grid_model_c/src/meta_data.cpp | 42 ++++++++--- .../power_grid_model_c/src/model.cpp | 71 +++++++++++-------- .../power_grid_model_c/src/serialization.cpp | 13 +++- 7 files changed, 163 insertions(+), 68 deletions(-) diff --git a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/basics.h b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/basics.h index 3e60e67f1b..f71714fd51 100644 --- a/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/basics.h +++ b/power_grid_model_c/power_grid_model_c/include/power_grid_model_c/basics.h @@ -81,7 +81,6 @@ typedef struct PGM_Options PGM_Options; // Only enable the opaque struct definition if this header is consumed by the C-API user. // If this header is included when compiling the C-API, the structs below are decleared/defined in the C++ files. -#ifndef PGM_DLL_EXPORTS /** * @brief Opaque struct for the attribute meta class. * @@ -137,7 +136,6 @@ typedef struct PGM_WritableDataset PGM_WritableDataset; * @brief Opaque struct for the information of the dataset. */ typedef struct PGM_DatasetInfo PGM_DatasetInfo; -#endif // NOLINTEND(modernize-use-using) diff --git a/power_grid_model_c/power_grid_model_c/src/buffer.cpp b/power_grid_model_c/power_grid_model_c/src/buffer.cpp index 4df924640f..f3f66d1004 100644 --- a/power_grid_model_c/power_grid_model_c/src/buffer.cpp +++ b/power_grid_model_c/power_grid_model_c/src/buffer.cpp @@ -17,6 +17,7 @@ namespace { using namespace power_grid_model; +using meta_data::MetaAttribute; using meta_data::RawDataConstPtr; using meta_data::RawDataPtr; using power_grid_model_c::call_with_catch; @@ -24,12 +25,13 @@ using power_grid_model_c::safe_ptr; using power_grid_model_c::safe_ptr_get; using power_grid_model_c::safe_ptr_maybe_nullptr; using power_grid_model_c::to_c_size; +using power_grid_model_c::unwrap; } // namespace // buffer control RawDataPtr PGM_create_buffer(PGM_Handle* handle, PGM_MetaComponent const* component, PGM_Idx size) { return call_with_catch(handle, [component, size] { - auto const& safe_component = safe_ptr_get(component); + auto const& safe_component = unwrap(safe_ptr_get(component)); // alignment should be maximum of alignment of the component and alignment of void* size_t const alignment = std::max(safe_component.alignment, sizeof(void*)); @@ -54,14 +56,14 @@ void PGM_destroy_buffer(RawDataPtr ptr) { void PGM_buffer_set_nan(PGM_Handle* handle, PGM_MetaComponent const* component, void* ptr, PGM_Idx buffer_offset, PGM_Idx size) { call_with_catch(handle, [component, ptr, buffer_offset, size] { - safe_ptr_get(component).set_nan(safe_ptr(ptr), buffer_offset, size); + unwrap(safe_ptr_get(component)).set_nan(safe_ptr(ptr), buffer_offset, size); }); } namespace { // template for get and set attribute template -void buffer_get_set_value(PGM_MetaAttribute const& attribute, BufferPtr buffer_ptr, ValuePtr value_ptr, +void buffer_get_set_value(MetaAttribute const& attribute, BufferPtr buffer_ptr, ValuePtr value_ptr, PGM_Idx buffer_offset, PGM_Idx size, PGM_Idx stride) { using RawValuePtr = std::conditional_t; @@ -90,14 +92,14 @@ void buffer_get_set_value(PGM_MetaAttribute const& attribute, BufferPtr buffer_p void PGM_buffer_set_value(PGM_Handle* handle, PGM_MetaAttribute const* attribute, RawDataPtr buffer_ptr, RawDataConstPtr src_ptr, PGM_Idx buffer_offset, PGM_Idx size, PGM_Idx src_stride) { call_with_catch(handle, [attribute, buffer_ptr, src_ptr, buffer_offset, size, src_stride] { - buffer_get_set_value(safe_ptr_get(attribute), safe_ptr_maybe_nullptr(buffer_ptr), + buffer_get_set_value(unwrap(safe_ptr_get(attribute)), safe_ptr_maybe_nullptr(buffer_ptr), safe_ptr_maybe_nullptr(src_ptr), buffer_offset, size, src_stride); }); } void PGM_buffer_get_value(PGM_Handle* handle, PGM_MetaAttribute const* attribute, RawDataConstPtr buffer_ptr, RawDataPtr dest_ptr, PGM_Idx buffer_offset, PGM_Idx size, PGM_Idx dest_stride) { call_with_catch(handle, [attribute, buffer_ptr, dest_ptr, buffer_offset, size, dest_stride] { - buffer_get_set_value(safe_ptr_get(attribute), safe_ptr_maybe_nullptr(buffer_ptr), + buffer_get_set_value(unwrap(safe_ptr_get(attribute)), safe_ptr_maybe_nullptr(buffer_ptr), safe_ptr_maybe_nullptr(dest_ptr), buffer_offset, size, dest_stride); }); } diff --git a/power_grid_model_c/power_grid_model_c/src/dataset.cpp b/power_grid_model_c/power_grid_model_c/src/dataset.cpp index 5c43824999..de3ce48611 100644 --- a/power_grid_model_c/power_grid_model_c/src/dataset.cpp +++ b/power_grid_model_c/power_grid_model_c/src/dataset.cpp @@ -15,6 +15,7 @@ #include #include +namespace { using namespace power_grid_model; using namespace power_grid_model::meta_data; using power_grid_model_c::call_with_catch; @@ -25,6 +26,37 @@ using power_grid_model_c::safe_ptr_maybe_nullptr; using power_grid_model_c::safe_str_view; using power_grid_model_c::to_c_bool; using power_grid_model_c::to_c_size; +using power_grid_model_c::wrap; +} // namespace + +struct PGM_ConstDataset : public power_grid_model::meta_data::ConstDataset { + using Dataset::Dataset; +}; +struct PGM_MutableDataset : public power_grid_model::meta_data::MutableDataset { + using Dataset::Dataset; +}; +struct PGM_WritableDataset : public power_grid_model::meta_data::WritableDataset { + using Dataset::Dataset; +}; +struct PGM_DatasetInfo : public power_grid_model::meta_data::DatasetInfo {}; + +namespace power_grid_model_c { +ConstDataset const* unwrap(PGM_ConstDataset const* instance) { + return static_cast(instance); // may invoke undefined behavior +} +ConstDataset const& unwrap(PGM_ConstDataset const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +MutableDataset const& unwrap(PGM_MutableDataset const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +PGM_WritableDataset& wrap(WritableDataset& instance) { + return static_cast(instance); // may invoke undefined behavior +} +PGM_DatasetInfo const& wrap(DatasetInfo const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +} // namespace power_grid_model_c // dataset info @@ -88,21 +120,21 @@ char const* PGM_dataset_info_attribute_name(PGM_Handle* handle, PGM_DatasetInfo PGM_ConstDataset* PGM_create_dataset_const(PGM_Handle* handle, char const* dataset, PGM_Idx is_batch, PGM_Idx batch_size) { return call_with_catch(handle, [dataset, is_batch, batch_size] { - return new ConstDataset{// NOSONAR(S5025) - safe_bool(is_batch), batch_size, safe_str_view(dataset), get_meta_data()}; + return new PGM_ConstDataset{// NOSONAR(S5025) + safe_bool(is_batch), batch_size, safe_str_view(dataset), get_meta_data()}; }); } PGM_ConstDataset* PGM_create_dataset_const_from_writable(PGM_Handle* handle, PGM_WritableDataset const* writable_dataset) { return call_with_catch(handle, [writable_dataset] { - return new ConstDataset{safe_ptr_get(writable_dataset)}; // NOSONAR(S5025) + return new PGM_ConstDataset{safe_ptr_get(writable_dataset)}; // NOSONAR(S5025) }); } PGM_ConstDataset* PGM_create_dataset_const_from_mutable(PGM_Handle* handle, PGM_MutableDataset const* mutable_dataset) { return call_with_catch(handle, [mutable_dataset] { - return new ConstDataset{safe_ptr_get(mutable_dataset)}; // NOSONAR(S5025) + return new PGM_ConstDataset{safe_ptr_get(mutable_dataset)}; // NOSONAR(S5025) }); } @@ -133,13 +165,13 @@ void PGM_dataset_const_set_next_cartesian_product_dimension(PGM_Handle* handle, } PGM_DatasetInfo const* PGM_dataset_const_get_info(PGM_Handle* handle, PGM_ConstDataset const* dataset) { - return call_with_catch(handle, [dataset] { return &safe_ptr_get(dataset).get_description(); }); + return call_with_catch(handle, [dataset] { return &wrap(safe_ptr_get(dataset).get_description()); }); } // writable dataset PGM_DatasetInfo const* PGM_dataset_writable_get_info(PGM_Handle* handle, PGM_WritableDataset const* dataset) { - return call_with_catch(handle, [dataset] { return &safe_ptr_get(dataset).get_description(); }); + return call_with_catch(handle, [dataset] { return &wrap(safe_ptr_get(dataset).get_description()); }); } void PGM_dataset_writable_set_buffer(PGM_Handle* handle, PGM_WritableDataset* dataset, char const* component, @@ -162,8 +194,8 @@ void PGM_dataset_writable_set_attribute_buffer(PGM_Handle* handle, PGM_WritableD PGM_MutableDataset* PGM_create_dataset_mutable(PGM_Handle* handle, char const* dataset, PGM_Idx is_batch, PGM_Idx batch_size) { return call_with_catch(handle, [dataset, is_batch, batch_size] { - return new MutableDataset{// NOSONAR(S5025) - safe_bool(is_batch), batch_size, safe_str_view(dataset), get_meta_data()}; + return new PGM_MutableDataset{// NOSONAR(S5025) + safe_bool(is_batch), batch_size, safe_str_view(dataset), get_meta_data()}; }); } @@ -188,5 +220,5 @@ void PGM_dataset_mutable_add_attribute_buffer(PGM_Handle* handle, PGM_MutableDat } PGM_DatasetInfo const* PGM_dataset_mutable_get_info(PGM_Handle* handle, PGM_MutableDataset const* dataset) { - return call_with_catch(handle, [dataset] { return &safe_ptr_get(dataset).get_description(); }); + return call_with_catch(handle, [dataset] { return &wrap(safe_ptr_get(dataset).get_description()); }); } diff --git a/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp b/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp index f68d7def3f..56c12cd9a5 100644 --- a/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp +++ b/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp @@ -10,8 +10,10 @@ #include -// forward declare all referenced struct/class in C++ core -// alias them in the root namespace +#include "power_grid_model_c/basics.h" + +// // forward declare all referenced struct/class in C++ core +// // alias them in the root namespace namespace power_grid_model::meta_data { @@ -22,17 +24,34 @@ class Serializer; class Deserializer; template class Dataset; +using ConstDataset = Dataset; +using MutableDataset = Dataset; +using WritableDataset = Dataset; struct DatasetInfo; } // namespace power_grid_model::meta_data -using PGM_MetaAttribute = power_grid_model::meta_data::MetaAttribute; -using PGM_MetaComponent = power_grid_model::meta_data::MetaComponent; -using PGM_MetaDataset = power_grid_model::meta_data::MetaDataset; -using PGM_Serializer = power_grid_model::meta_data::Serializer; -using PGM_Deserializer = power_grid_model::meta_data::Deserializer; -using PGM_ConstDataset = power_grid_model::meta_data::Dataset; -using PGM_MutableDataset = power_grid_model::meta_data::Dataset; -using PGM_WritableDataset = power_grid_model::meta_data::Dataset; -using PGM_DatasetInfo = power_grid_model::meta_data::DatasetInfo; +namespace power_grid_model_c { +using power_grid_model::meta_data::ConstDataset; +using power_grid_model::meta_data::Dataset; +using power_grid_model::meta_data::DatasetInfo; +using power_grid_model::meta_data::Deserializer; +using power_grid_model::meta_data::MetaAttribute; +using power_grid_model::meta_data::MetaComponent; +using power_grid_model::meta_data::MetaDataset; +using power_grid_model::meta_data::MutableDataset; +using power_grid_model::meta_data::Serializer; +using power_grid_model::meta_data::WritableDataset; + +MetaComponent const& unwrap(PGM_MetaComponent const&); +MetaAttribute const& unwrap(PGM_MetaAttribute const&); +ConstDataset const& unwrap(PGM_ConstDataset const&); +ConstDataset const* unwrap(PGM_ConstDataset const*); +MutableDataset const& unwrap(PGM_MutableDataset const&); +PGM_WritableDataset& wrap(WritableDataset&); +PGM_DatasetInfo const& wrap(DatasetInfo const&); +PGM_MetaDataset const& wrap(MetaDataset const&); +PGM_MetaComponent const& wrap(MetaComponent const&); +PGM_MetaAttribute const& wrap(MetaAttribute const&); +} // namespace power_grid_model_c diff --git a/power_grid_model_c/power_grid_model_c/src/meta_data.cpp b/power_grid_model_c/power_grid_model_c/src/meta_data.cpp index bc31abdcd2..5240a5e306 100644 --- a/power_grid_model_c/power_grid_model_c/src/meta_data.cpp +++ b/power_grid_model_c/power_grid_model_c/src/meta_data.cpp @@ -24,6 +24,7 @@ using power_grid_model_c::safe_ptr_get; using power_grid_model_c::safe_str_view; using power_grid_model_c::to_c_bool; using power_grid_model_c::to_c_enum; +using power_grid_model_c::wrap; // assert index type static_assert(std::is_same_v); @@ -49,6 +50,28 @@ struct RangedExceptionHandler : public power_grid_model_c::DefaultExceptionHandl constexpr RangedExceptionHandler ranged_exception_handler{}; } // namespace +struct PGM_MetaAttribute : public power_grid_model::meta_data::MetaAttribute {}; +struct PGM_MetaComponent : public power_grid_model::meta_data::MetaComponent {}; +struct PGM_MetaDataset : public power_grid_model::meta_data::MetaDataset {}; + +namespace power_grid_model_c { +MetaComponent const& unwrap(PGM_MetaComponent const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +MetaAttribute const& unwrap(PGM_MetaAttribute const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +PGM_MetaAttribute const& wrap(MetaAttribute const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +PGM_MetaComponent const& wrap(MetaComponent const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +PGM_MetaDataset const& wrap(MetaDataset const& instance) { + return static_cast(instance); // may invoke undefined behavior +} +} // namespace power_grid_model_c + // retrieve meta data power_grid_model::meta_data::MetaData const& get_meta_data() { return power_grid_model::meta_data::meta_data_gen::meta_data; @@ -63,13 +86,14 @@ PGM_MetaDataset const* PGM_meta_get_dataset_by_idx(PGM_Handle* handle, PGM_Idx i if (idx < 0 || idx >= get_meta_data().n_datasets()) { throw std::out_of_range{"Index out of range!\n"}; } - return &get_meta_data().datasets[idx]; + return &wrap(get_meta_data().datasets[idx]); }, ranged_exception_handler); } PGM_MetaDataset const* PGM_meta_get_dataset_by_name(PGM_Handle* handle, char const* dataset) { return call_with_catch( - handle, [dataset] { return &get_meta_data().get_dataset(safe_str_view(dataset)); }, ranged_exception_handler); + handle, [dataset] { return &wrap(get_meta_data().get_dataset(safe_str_view(dataset))); }, + ranged_exception_handler); } char const* PGM_meta_dataset_name(PGM_Handle* handle, PGM_MetaDataset const* dataset) { return call_with_catch(handle, [dataset] { return safe_ptr_get(dataset).name; }); @@ -87,7 +111,7 @@ PGM_MetaComponent const* PGM_meta_get_component_by_idx(PGM_Handle* handle, PGM_M if (idx < 0 || idx >= safe_dataset.n_components()) { throw std::out_of_range{"Index out of range!\n"}; } - return &safe_dataset.components[idx]; + return &wrap(safe_dataset.components[idx]); }, ranged_exception_handler); } @@ -96,7 +120,7 @@ PGM_MetaComponent const* PGM_meta_get_component_by_name(PGM_Handle* handle, char return call_with_catch( handle, [component, dataset] { - return &get_meta_data().get_dataset(safe_str_view(dataset)).get_component(safe_str_view(component)); + return &wrap(get_meta_data().get_dataset(safe_str_view(dataset)).get_component(safe_str_view(component))); }, ranged_exception_handler); } @@ -122,7 +146,7 @@ PGM_MetaAttribute const* PGM_meta_get_attribute_by_idx(PGM_Handle* handle, PGM_M if (idx < 0 || idx >= safe_component.n_attributes()) { throw std::out_of_range{"Index out of range!\n"}; } - return &safe_component.attributes[idx]; + return &wrap(safe_component.attributes[idx]); }, ranged_exception_handler); } @@ -131,10 +155,10 @@ PGM_MetaAttribute const* PGM_meta_get_attribute_by_name(PGM_Handle* handle, char return call_with_catch( handle, [component, dataset, attribute] { - return &get_meta_data() - .get_dataset(safe_str_view(dataset)) - .get_component(safe_str_view(component)) - .get_attribute(safe_str_view(attribute)); + return &wrap(get_meta_data() + .get_dataset(safe_str_view(dataset)) + .get_component(safe_str_view(component)) + .get_attribute(safe_str_view(attribute))); }, ranged_exception_handler); } diff --git a/power_grid_model_c/power_grid_model_c/src/model.cpp b/power_grid_model_c/power_grid_model_c/src/model.cpp index 00ab5bee39..70eececcd9 100644 --- a/power_grid_model_c/power_grid_model_c/src/model.cpp +++ b/power_grid_model_c/power_grid_model_c/src/model.cpp @@ -29,6 +29,7 @@ using power_grid_model_c::safe_ptr; using power_grid_model_c::safe_ptr_get; using power_grid_model_c::safe_ptr_maybe_nullptr; using power_grid_model_c::safe_str_view; +using power_grid_model_c::unwrap; } // namespace // aliases main class @@ -41,14 +42,15 @@ PGM_PowerGridModel* PGM_create_model(PGM_Handle* handle, double system_frequency PGM_ConstDataset const* input_dataset) { return call_with_catch(handle, [system_frequency, input_dataset] { return new PGM_PowerGridModel{// NOSONAR(S5025) - system_frequency, safe_ptr_get(input_dataset), get_math_solver_dispatcher(), 0}; + system_frequency, unwrap(safe_ptr_get(input_dataset)), + get_math_solver_dispatcher(), 0}; }); } // update model void PGM_update_model(PGM_Handle* handle, PGM_PowerGridModel* model, PGM_ConstDataset const* update_dataset) { call_with_catch(handle, [model, update_dataset] { - model->update_components(safe_ptr_get(update_dataset)); + safe_ptr_get(model).update_components(unwrap(safe_ptr_get(update_dataset))); }); } @@ -157,7 +159,7 @@ class BadCalculationRequest : public PowerGridError { explicit BadCalculationRequest(std::string msg) : PowerGridError{std::move(msg)} {} }; -void calculate_single_batch_dimension_impl(PGM_PowerGridModel& model, PGM_Options const& opt, +void calculate_single_batch_dimension_impl(MainModel& model, MainModel::Options const& options, MutableDataset const& output_dataset, ConstDataset const* batch_dataset) { // check dataset integrity if ((batch_dataset != nullptr) && (!batch_dataset->is_batch() || !output_dataset.is_batch())) { @@ -165,16 +167,9 @@ void calculate_single_batch_dimension_impl(PGM_PowerGridModel& model, PGM_Option "If batch_dataset is provided. Both batch_dataset and output_dataset should be a batch!\n"}; } - ConstDataset const& exported_update_dataset = - batch_dataset != nullptr ? safe_ptr_get(batch_dataset) - : PGM_ConstDataset{false, 1, "update", output_dataset.meta_data()}; - - check_calculate_valid_options(opt); - auto const options = extract_calculation_options(opt); - - if (opt.experimental_features == PGM_experimental_features_disabled) { - check_no_experimental_features_used(model, options); - } + ConstDataset const& exported_update_dataset = batch_dataset != nullptr + ? safe_ptr_get(batch_dataset) + : ConstDataset{false, 1, "update", output_dataset.meta_data()}; model.calculate(options, output_dataset, exported_update_dataset); } @@ -240,31 +235,35 @@ class MDBatchExceptionHandler : public power_grid_model_c::DefaultExceptionHandl Idx stride_size_{}; }; -Idx get_batch_dimension(PGM_ConstDataset const* batch_dataset) { +Idx get_batch_dimension(ConstDataset const* batch_dataset) { Idx dimension = 0; - while (batch_dataset != nullptr) { + ConstDataset const* safe_batch_dataset = safe_ptr_maybe_nullptr(batch_dataset); + while (safe_batch_dataset != nullptr) { ++dimension; - batch_dataset = batch_dataset->get_next_cartesian_product_dimension(); + safe_batch_dataset = + safe_ptr_maybe_nullptr(safe_ptr_get(safe_batch_dataset).get_next_cartesian_product_dimension()); } return dimension; } -Idx get_stride_size(PGM_ConstDataset const* batch_dataset) { +Idx get_stride_size(ConstDataset const* batch_dataset) { Idx size = 1; - PGM_ConstDataset const* current = batch_dataset->get_next_cartesian_product_dimension(); + ConstDataset const* current = + safe_ptr_maybe_nullptr(safe_ptr_get(batch_dataset).get_next_cartesian_product_dimension()); while (current != nullptr) { - size *= current->batch_size(); - current = current->get_next_cartesian_product_dimension(); + auto const& safe_current = safe_ptr_get(current); + size *= safe_current.batch_size(); + current = safe_current.get_next_cartesian_product_dimension(); } return size; } // run calculation -void calculate_multi_dimensional_impl(PGM_PowerGridModel& model, PGM_Options const& opt, - PGM_MutableDataset const& output_dataset, PGM_ConstDataset const* batch_dataset) { +void calculate_multi_dimensional_impl(MainModel& model, MainModel::Options const& options, + MutableDataset const& output_dataset, ConstDataset const* batch_dataset) { // for dimension < 2 (one-time or 1D batch), call implementation directly if (auto const batch_dimension = get_batch_dimension(batch_dataset); batch_dimension < 2) { - calculate_single_batch_dimension_impl(model, opt, output_dataset, batch_dataset); + calculate_single_batch_dimension_impl(model, options, output_dataset, batch_dataset); return; } @@ -281,20 +280,20 @@ void calculate_multi_dimensional_impl(PGM_PowerGridModel& model, PGM_Options con // a new handle call_with_catch( &local_handle, - [&model, &opt, &output_dataset, &safe_batch_dataset, i, stride_size] { + [&model, &options, &output_dataset, &safe_batch_dataset, i, stride_size] { // create sliced datasets for the rest of dimensions - PGM_ConstDataset const single_update_dataset = safe_batch_dataset.get_individual_scenario(i); - PGM_MutableDataset const sliced_output_dataset = + ConstDataset const single_update_dataset = safe_batch_dataset.get_individual_scenario(i); + MutableDataset const sliced_output_dataset = output_dataset.get_slice_scenario(i * stride_size, (i + 1) * stride_size); // create a model copy - PGM_PowerGridModel local_model{model}; + MainModel local_model{model}; // apply the update local_model.update_components(single_update_dataset); // recursive call - calculate_multi_dimensional_impl(local_model, opt, sliced_output_dataset, + calculate_multi_dimensional_impl(local_model, options, sliced_output_dataset, safe_batch_dataset.get_next_cartesian_product_dimension()); }, MDBatchExceptionHandler{i * stride_size, stride_size}); @@ -306,6 +305,18 @@ void calculate_multi_dimensional_impl(PGM_PowerGridModel& model, PGM_Options con } } +void calculate_impl(MainModel& model, PGM_Options const& options, MutableDataset const& output_dataset, + ConstDataset const* batch_dataset) { + check_calculate_valid_options(options); + auto const extracted_options = extract_calculation_options(options); + + if (options.experimental_features == PGM_experimental_features_disabled) { + check_no_experimental_features_used(model, extracted_options); + } + + calculate_multi_dimensional_impl(model, extracted_options, output_dataset, batch_dataset); +} + } // namespace // run calculation @@ -314,8 +325,8 @@ void PGM_calculate(PGM_Handle* handle, PGM_PowerGridModel* model, PGM_Options co call_with_catch( handle, [model, opt, output_dataset, batch_dataset] { - calculate_multi_dimensional_impl(safe_ptr_get(model), safe_ptr_get(opt), safe_ptr_get(output_dataset), - safe_ptr_maybe_nullptr(batch_dataset)); + calculate_impl(safe_ptr_get(model), safe_ptr_get(opt), unwrap(safe_ptr_get(output_dataset)), + unwrap(safe_ptr_maybe_nullptr(batch_dataset))); }, batch_exception_handler); } diff --git a/power_grid_model_c/power_grid_model_c/src/serialization.cpp b/power_grid_model_c/power_grid_model_c/src/serialization.cpp index 44b2c8d077..1407c059e6 100644 --- a/power_grid_model_c/power_grid_model_c/src/serialization.cpp +++ b/power_grid_model_c/power_grid_model_c/src/serialization.cpp @@ -27,6 +27,8 @@ using power_grid_model_c::safe_ptr; using power_grid_model_c::safe_ptr_get; using power_grid_model_c::safe_size; using power_grid_model_c::to_c_size; +using power_grid_model_c::unwrap; +using power_grid_model_c::wrap; struct SerializationExceptionHandler : public power_grid_model_c::DefaultExceptionHandler { void operator()(PGM_Handle& handle) const noexcept { handle_all_errors(handle, PGM_serialization_error); } @@ -35,6 +37,13 @@ struct SerializationExceptionHandler : public power_grid_model_c::DefaultExcepti constexpr SerializationExceptionHandler serialization_exception_handler{}; } // namespace +struct PGM_Serializer : public power_grid_model::meta_data::Serializer { + using Serializer::Serializer; +}; +struct PGM_Deserializer : public power_grid_model::meta_data::Deserializer { + using Deserializer::Deserializer; +}; + PGM_Deserializer* PGM_create_deserializer_from_binary_buffer(PGM_Handle* handle, char const* data, PGM_Idx size, PGM_Idx serialization_format) { return call_with_catch( @@ -63,7 +72,7 @@ PGM_Deserializer* PGM_create_deserializer_from_null_terminated_string(PGM_Handle } PGM_WritableDataset* PGM_deserializer_get_dataset(PGM_Handle* handle, PGM_Deserializer* deserializer) { - return call_with_catch(handle, [deserializer] { return &safe_ptr_get(deserializer).get_dataset_info(); }); + return call_with_catch(handle, [deserializer] { return &wrap(safe_ptr_get(deserializer).get_dataset_info()); }); } void PGM_deserializer_parse_to_buffer(PGM_Handle* handle, PGM_Deserializer* deserializer) { @@ -82,7 +91,7 @@ PGM_Serializer* PGM_create_serializer(PGM_Handle* handle, PGM_ConstDataset const handle, [dataset, serialization_format] { return new PGM_Serializer{// NOSONAR(S5025) - safe_ptr_get(dataset), + unwrap(safe_ptr_get(dataset)), safe_enum(serialization_format)}; }, serialization_exception_handler); From b2504f1ecab7e3dde9a35c8b87c79bd9f1c1488f Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 19 Jan 2026 11:32:48 +0100 Subject: [PATCH 2/2] resolve comments Signed-off-by: Martijn Govers --- .../include/power_grid_model/topology.hpp | 2 +- .../power_grid_model_c/src/dataset.cpp | 29 ------------------- .../src/forward_declarations.hpp | 3 -- 3 files changed, 1 insertion(+), 33 deletions(-) diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/topology.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/topology.hpp index 95d3884d3f..e707dd97e2 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/topology.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/topology.hpp @@ -356,7 +356,7 @@ class Topology { for (auto&& [idx, branch_node_idx, branch_connected] : std::views::zip(std::views::iota(0), std::as_const(comp_topo_.branch_node_idx), std::as_const(comp_conn_.branch_connected))) { - assert(std::ssize(branch_connected) == 2); + assert(std::ssize(branch_connected) == 2); // NOSONAR(R354) auto const [i, j] = branch_node_idx; IntS const i_status = branch_connected[0]; diff --git a/power_grid_model_c/power_grid_model_c/src/dataset.cpp b/power_grid_model_c/power_grid_model_c/src/dataset.cpp index fb83dc8be7..5b1115b2f4 100644 --- a/power_grid_model_c/power_grid_model_c/src/dataset.cpp +++ b/power_grid_model_c/power_grid_model_c/src/dataset.cpp @@ -30,35 +30,6 @@ using power_grid_model_c::to_c_bool; using power_grid_model_c::to_c_size; } // namespace -struct PGM_ConstDataset : public power_grid_model::meta_data::ConstDataset { - using Dataset::Dataset; -}; -struct PGM_MutableDataset : public power_grid_model::meta_data::MutableDataset { - using Dataset::Dataset; -}; -struct PGM_WritableDataset : public power_grid_model::meta_data::WritableDataset { - using Dataset::Dataset; -}; -struct PGM_DatasetInfo : public power_grid_model::meta_data::DatasetInfo {}; - -namespace power_grid_model_c { -ConstDataset const* unwrap(PGM_ConstDataset const* instance) { - return static_cast(instance); // may invoke undefined behavior -} -ConstDataset const& unwrap(PGM_ConstDataset const& instance) { - return static_cast(instance); // may invoke undefined behavior -} -MutableDataset const& unwrap(PGM_MutableDataset const& instance) { - return static_cast(instance); // may invoke undefined behavior -} -PGM_WritableDataset& wrap(WritableDataset& instance) { - return static_cast(instance); // may invoke undefined behavior -} -PGM_DatasetInfo const& wrap(DatasetInfo const& instance) { - return static_cast(instance); // may invoke undefined behavior -} -} // namespace power_grid_model_c - // dataset info char const* PGM_dataset_info_name(PGM_Handle* handle, PGM_DatasetInfo const* info) { diff --git a/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp b/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp index f8103eac8d..6dfcd0684b 100644 --- a/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp +++ b/power_grid_model_c/power_grid_model_c/src/forward_declarations.hpp @@ -26,9 +26,6 @@ class Serializer; class Deserializer; template class Dataset; -using ConstDataset = Dataset; -using MutableDataset = Dataset; -using WritableDataset = Dataset; struct DatasetInfo;