Repository navigation
Initial lambda extraction #566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
9134b94
initial lambda extraction
lukelowry 1ef253e
older model migration and unify with new helper
lukelowry af676ad
improved config checks and parameter reader
lukelowry 586783a
Apply pre-commit fixes
lukelowry 7c932a9
misc formatting changes per reviewers
lukelowry d2a45f2
Apply pre-commit fixes
lukelowry cb6b63c
reduce scope
lukelowry ab56864
polish and improve available Readers and Checkers
lukelowry 7cadc6b
Update GridKit/Testing/Testing.hpp
lukelowry 6baa495
Adjust and cleanup per reviewer comments
lukelowry fdff03b
empty overrides
lukelowry File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| /** | ||
| * @file ConfigurationChecks.hpp | ||
| * @author Luke Lowery (lukel@tamu.edu) | ||
| * @brief Collects the configuration problems found by a model. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <format> | ||
| #include <string> | ||
| #include <string_view> | ||
| #include <vector> | ||
|
|
||
| namespace GridKit | ||
| { | ||
| namespace Model | ||
| { | ||
| /** | ||
| * @brief Collects the configuration problems found by a model. | ||
| * | ||
| * A model's verify() fills one instance with a message for every | ||
| * condition that does not hold and returns it. The caller decides how | ||
| * the messages are reported; passed() is true when there are none. | ||
| */ | ||
| class [[nodiscard]] ConfigurationChecks | ||
| { | ||
| public: | ||
| ConfigurationChecks() = default; | ||
|
|
||
| /// @param[in] model Model name that prefixes every recorded message. | ||
| explicit ConfigurationChecks(std::string_view model) | ||
| : prefix_(std::format("{}: ", model)) | ||
| { | ||
| } | ||
|
|
||
| /// Record a problem. | ||
| void fail(std::string_view message) | ||
| { | ||
| errors_.push_back(prefix_ + std::string(message)); | ||
| } | ||
|
|
||
| /// Record the message when the condition does not hold. | ||
| void check(bool condition, std::string_view message) | ||
| { | ||
| if (!condition) | ||
| { | ||
| fail(message); | ||
| } | ||
| } | ||
|
|
||
| /// True when no check has failed. | ||
| bool passed() const | ||
| { | ||
| return errors_.empty(); | ||
| } | ||
|
|
||
| /// Every recorded message, in the order the checks ran. | ||
| const std::vector<std::string>& errors() const | ||
| { | ||
| return errors_; | ||
| } | ||
|
|
||
| private: | ||
| std::string prefix_; | ||
| std::vector<std::string> errors_; | ||
| }; | ||
| } // namespace Model | ||
| } // namespace GridKit | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| /** | ||
| * @file ParameterReader.hpp | ||
| * @author Luke Lowery (lukel@tamu.edu) | ||
| * @brief Typed parameter loading from model data containers. | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <cmath> | ||
| #include <format> | ||
| #include <optional> | ||
| #include <stdexcept> | ||
| #include <string_view> | ||
| #include <variant> | ||
|
|
||
| #include <magic_enum/magic_enum.hpp> | ||
|
|
||
| #include <GridKit/Constants.hpp> | ||
| #include <GridKit/Model/PhasorDynamics/ModelData.hpp> | ||
|
|
||
| namespace GridKit | ||
| { | ||
| namespace Model | ||
| { | ||
| /** | ||
| * @brief Reads typed parameters out of a model data container. | ||
| * | ||
| * A read method returns the provided value or std::nullopt when the | ||
| * parameter is omitted. The model chooses a default or requires a value. | ||
| * Invalid values are rejected with std::invalid_argument naming the | ||
| * model and parameter. Real parameters accept integer values and must | ||
| * be finite. | ||
| * | ||
| * @tparam ModelDataT A model data container satisfying | ||
| * PhasorDynamics::ModelData. | ||
| */ | ||
| template <PhasorDynamics::ModelData ModelDataT> | ||
| class ParameterReader | ||
|
superwhiskers marked this conversation as resolved.
Resolved
|
||
| { | ||
| public: | ||
| using RealT = typename ModelDataT::RealT; | ||
| using IdxT = typename ModelDataT::IdxT; | ||
| using ParametersT = typename ModelDataT::Parameters; | ||
|
|
||
| /** | ||
| * @param[in] data Model data container to read from. | ||
| * @param[in] model Model name used in rejection messages. | ||
| */ | ||
| ParameterReader(const ModelDataT& data, const char* model) | ||
| : parameters_(data.parameters), | ||
| model_(model) | ||
| { | ||
| } | ||
|
|
||
| /// Read an optional real parameter. | ||
| [[nodiscard]] std::optional<RealT> readReal(ParametersT key) const | ||
| { | ||
| const auto* value = find(key); | ||
| if (value == nullptr) | ||
| { | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| RealT real{}; | ||
| if (const auto* real_value = std::get_if<RealT>(value)) | ||
| { | ||
| real = *real_value; | ||
| } | ||
| else if (const auto* integer_value = std::get_if<IdxT>(value)) | ||
| { | ||
| real = static_cast<RealT>(*integer_value); | ||
| } | ||
| else | ||
| { | ||
| reject(key, "must be numeric"); | ||
| } | ||
|
|
||
| if (!std::isfinite(real)) | ||
| { | ||
| reject(key, "must be finite"); | ||
| } | ||
|
|
||
| return real; | ||
| } | ||
|
|
||
| /// Read an optional non-negative real parameter. | ||
| [[nodiscard]] std::optional<RealT> readNonNegative(ParametersT key) const | ||
| { | ||
| auto value = readReal(key); | ||
| if (value && *value < ZERO<RealT>) | ||
| { | ||
| reject(key, "must be non-negative"); | ||
| } | ||
| return value; | ||
| } | ||
|
|
||
| /// Read an optional boolean parameter. | ||
| [[nodiscard]] std::optional<bool> readBool(ParametersT key) const | ||
| { | ||
| return readExact<bool>(key, "must be boolean"); | ||
| } | ||
|
|
||
| /// Read an optional integer parameter. | ||
| [[nodiscard]] std::optional<IdxT> readInteger(ParametersT key) const | ||
| { | ||
| return readExact<IdxT>(key, "must be an integer"); | ||
| } | ||
|
|
||
| private: | ||
| using ParameterMapT = decltype(ModelDataT::parameters); | ||
| using ValueT = typename ParameterMapT::mapped_type; | ||
|
|
||
| /// The provided value, or nullptr when the parameter is omitted. | ||
| const ValueT* find(ParametersT key) const | ||
| { | ||
| const auto entry = parameters_.find(key); | ||
| if (entry == parameters_.end()) | ||
| { | ||
| return nullptr; | ||
| } | ||
| return &entry->second; | ||
| } | ||
|
|
||
| /// Read an optional parameter that must hold exactly a T. | ||
| template <typename T> | ||
| [[nodiscard]] std::optional<T> readExact(ParametersT key, std::string_view reason) const | ||
| { | ||
| const auto* value = find(key); | ||
| if (value == nullptr) | ||
| { | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| const auto* exact_value = std::get_if<T>(value); | ||
| if (exact_value == nullptr) | ||
| { | ||
| reject(key, reason); | ||
| } | ||
|
|
||
| return *exact_value; | ||
| } | ||
|
|
||
| /// Reject the model data with a message naming the model and parameter. | ||
| [[noreturn]] void reject(ParametersT key, std::string_view reason) const | ||
| { | ||
| throw std::invalid_argument( | ||
| std::format("{}: parameter '{}' {}", model_, magic_enum::enum_name(key), reason)); | ||
| } | ||
|
|
||
| const ParameterMapT& parameters_; | ||
| const char* model_; | ||
| }; | ||
| } // namespace Model | ||
| } // namespace GridKit | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.