From e2f2ac57fca5eef5c4ecd3e698abf001d7ab4243 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:22:47 -0700 Subject: [PATCH 1/6] C++20 is strict about implict this's in lambdas --- src/gretl/data_store.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gretl/data_store.cpp b/src/gretl/data_store.cpp index 12288ac..68472bd 100644 --- a/src/gretl/data_store.cpp +++ b/src/gretl/data_store.cpp @@ -225,12 +225,12 @@ void DataStore::add_state(std::unique_ptr newState, const std::vector } } - evals_.emplace_back([=](const UpstreamStates&, DownstreamState&) { + evals_.emplace_back([this](const UpstreamStates&, DownstreamState&) { std::cout << "eval not implemented for step " << currentStep_ << std::endl; gretl_assert(false); }); - vjps_.emplace_back([=](UpstreamStates&, const DownstreamState&) { + vjps_.emplace_back([this](UpstreamStates&, const DownstreamState&) { std::cout << "vjp not implemented for step " << currentStep_ << std::endl; gretl_assert(false); }); From b23f49d93b7480e73bc596baad817e340d88ed57 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:24:01 -0700 Subject: [PATCH 2/6] clean up headers --- src/gretl/data_store.cpp | 2 +- src/gretl/state.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gretl/data_store.cpp b/src/gretl/data_store.cpp index 68472bd..9cb4b9c 100644 --- a/src/gretl/data_store.cpp +++ b/src/gretl/data_store.cpp @@ -4,9 +4,9 @@ // // SPDX-License-Identifier: (BSD-3-Clause) -#include #include "data_store.hpp" #include "state.hpp" +#include #include #include diff --git a/src/gretl/state.hpp b/src/gretl/state.hpp index c32acbd..68b4ef8 100644 --- a/src/gretl/state.hpp +++ b/src/gretl/state.hpp @@ -13,7 +13,6 @@ #include #include "upstream_state.hpp" #include "state_base.hpp" -#include "upstream_state.hpp" namespace gretl { From ae3861e544f80fdc8ce57f562d4a27c40e5b3b15 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:26:53 -0700 Subject: [PATCH 3/6] move UpstreamState/DownstreamState into same file as DataStore to get around C++20's strict requirement that std::any not have incomplete types --- src/gretl/data_store.hpp | 122 ++++++++++++++++++++++++++++++++++- src/gretl/upstream_state.hpp | 120 ---------------------------------- 2 files changed, 120 insertions(+), 122 deletions(-) delete mode 100644 src/gretl/upstream_state.hpp diff --git a/src/gretl/data_store.hpp b/src/gretl/data_store.hpp index e85fede..1acd78d 100644 --- a/src/gretl/data_store.hpp +++ b/src/gretl/data_store.hpp @@ -31,14 +31,96 @@ namespace gretl { using Int = unsigned int; ///< gretl Int type +class DataStore; + struct StateBase; template struct State; -struct UpstreamStates; +/// @brief UpstreamState is a wrapper for a states. Its used in external-facing interfaces to ensure const correctness +/// for users to encourage correct usage. +struct UpstreamState { + Int step_; ///< step + DataStore* dataStore_; ///< datastore + + /// @brief get underlying value + template + const T& get() const; + + /// @brief get underlying dual value + template + D& get_dual() const; +}; + +/// @brief UpstreamStates is a wrapper for a vector of states. Its used in external-facing interfaces to ensure const +/// correctness for users to encourage correct usage. +struct UpstreamStates { + /// @brief Default constructor to use in std containers + UpstreamStates() = default; + + /// @brief Constructor for upstream states + /// @param store datastore + /// @param steps vector of upstream steps + UpstreamStates(DataStore& store, std::vector steps) + { + for (Int s : steps) { + states_.push_back({s, &store}); + } + } + + /// @brief Accessor for individual upstream states + /// @param index index + template + const UpstreamState& operator[](IntT index) const + { + return states_[static_cast(index)]; + } + + /// @brief Accessor for individual upstream states + /// @param index index + const UpstreamState& operator[](Int index) const { return states_[index]; } + + /// @brief Number of upstream states + Int size() const { return static_cast(states_.size()); } + + /// @brief Vector of upstream step indices + const std::vector& states() const { return states_; } + + private: + std::vector states_; ///< states +}; + +/// @brief DownstreamState is a wrapper for a state. Its used in external-facing interfaces to ensure const correctness +/// for users to encourage correct usage. +struct DownstreamState { + /// @brief Constructor + /// @param s datastore + /// @param step step + DownstreamState(DataStore* s, Int step) : dataStore_(s), step_(step) {} + + /// @brief set underlying value (copy) + template + void set(const T& t); + + /// @brief set underlying value (move) + template > + void set(T&& t); + + /// @brief get underlying value + template + const T& get() const; + + /// @brief get underlying dual value + template + const D& get_dual() const; -struct DownstreamState; + friend class DataStore; + + private: + DataStore* dataStore_; ///< datastore + Int step_; ///< step +}; /// @brief ZeroDual function type template @@ -275,4 +357,40 @@ class DataStore { friend struct DownstreamState; }; +template +const T& UpstreamState::get() const +{ + return dataStore_->get_primal(step_); +} + +template +D& UpstreamState::get_dual() const +{ + return dataStore_->get_dual(step_); +} + +template +void DownstreamState::set(const T& t) +{ + dataStore_->set_primal(step_, t); +} + +template +void DownstreamState::set(T&& t) +{ + dataStore_->set_primal(step_, std::forward(t)); +} + +template +const T& DownstreamState::get() const +{ + return dataStore_->get_primal(step_); +} + +template +const D& DownstreamState::get_dual() const +{ + return dataStore_->get_dual(step_); +} + } // namespace gretl diff --git a/src/gretl/upstream_state.hpp b/src/gretl/upstream_state.hpp deleted file mode 100644 index c5235e4..0000000 --- a/src/gretl/upstream_state.hpp +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Lawrence Livermore National Security, LLC and -// other Gretl Project Developers. See the top-level LICENSE file for -// details. -// -// SPDX-License-Identifier: (BSD-3-Clause) - -/** - * @file upstream_state.hpp - */ - -#pragma once - -#include -#include "data_store.hpp" - -namespace gretl { - -/// @brief UpstreamState is a wrapper for a states. Its used in external-facing interfaces to ensure const correctness -/// for users to encourage correct usage. -struct UpstreamState { - Int step_; ///< step - DataStore* dataStore_; ///< datastore - - /// @brief get underlying value - template - const T& get() const - { - return dataStore_->get_primal(step_); - } - - /// @brief get underlying dual value - template - D& get_dual() const - { - return dataStore_->get_dual(step_); - } -}; - -/// @brief UpstreamStates is a wrapper for a vector of states. Its used in external-facing interfaces to ensure const -/// correctness for users to encourage correct usage. -struct UpstreamStates { - /// @brief Default constructor to use in std containers - UpstreamStates() {} - - /// @brief Constructor for upstream states - /// @param store datastore - /// @param steps vector of upstream steps - UpstreamStates(DataStore& store, std::vector steps) - { - for (Int s : steps) { - states_.push_back({s, &store}); - } - } - - /// @brief Accessor for individual upstream states - /// @param index index - template - const UpstreamState& operator[](IntT index) const - { - return states_[static_cast(index)]; - } - - /// @brief Accessor for individual upstream states - /// @param index index - const UpstreamState& operator[](Int index) const { return states_[index]; } - - /// @brief Number of upstream states - Int size() const { return static_cast(states_.size()); } - - /// @brief Vector of upstream step indices - const std::vector& states() const { return states_; } - - private: - std::vector states_; ///< states -}; - -/// @brief DownstreamState is a wrapper for a state. Its used in external-facing interfaces to ensure const correctness -/// for users to encourage correct usage. -struct DownstreamState { - /// @brief Constructor - /// @param s datastore - /// @param step step - DownstreamState(DataStore* s, Int step) : dataStore_(s), step_(step) {} - - /// @brief set underlying value (copy) - template - void set(const T& t) - { - dataStore_->set_primal(step_, t); - } - - /// @brief set underlying value (move) - template > - void set(T&& t) - { - dataStore_->set_primal(step_, std::forward(t)); - } - - /// @brief get underlying value - template - const T& get() const - { - return dataStore_->get_primal(step_); - } - - /// @brief get underlying dual value - template - const D& get_dual() const - { - return dataStore_->get_dual(step_); - } - - friend class DataStore; - - private: - DataStore* dataStore_; ///< datastore - Int step_; ///< step -}; - -} // namespace gretl From 60cc0016bb1f3f0d1af9dec7f660d82b212749ce Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:28:22 -0700 Subject: [PATCH 4/6] add ci check for C++20 --- .github/workflows/ci-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 188fa58..80ac002 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -38,6 +38,10 @@ jobs: host_config: llvm@19.1.1.cmake compiler_image: ${{ needs.set_image_vars.outputs.clang_docker_image }} cmake_opts: "-DBUILD_SHARED_LIBS=ON" + - job_name: llvm@19.1.1, C++20, shared + host_config: llvm@19.1.1.cmake + compiler_image: ${{ needs.set_image_vars.outputs.clang_docker_image }} + cmake_opts: "-DBUILD_SHARED_LIBS=ON -DBLT_CXX_STD=c++20" - job_name: gcc@14.2.0, shared host_config: gcc@14.2.0.cmake compiler_image: ${{ needs.set_image_vars.outputs.gcc_docker_image }} From 9bd3ab5ef3e013b48c214b3150e7a3917c8ef69a Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:37:16 -0700 Subject: [PATCH 5/6] remove header for cmake --- src/gretl/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gretl/CMakeLists.txt b/src/gretl/CMakeLists.txt index 12e9d4c..85b0be5 100644 --- a/src/gretl/CMakeLists.txt +++ b/src/gretl/CMakeLists.txt @@ -34,7 +34,6 @@ set(gretl_headers state_base.hpp state.hpp test_utils.hpp - upstream_state.hpp vector_state.hpp) blt_add_library(NAME gretl From 4fcbb6f2bcb0c470001c2b3779e9d53e33e3ff2d Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 16 Mar 2026 09:43:44 -0700 Subject: [PATCH 6/6] actually test the changes i do before pushing them --- src/gretl/create_state.hpp | 1 - src/gretl/state.hpp | 1 - src/gretl/state_base.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/src/gretl/create_state.hpp b/src/gretl/create_state.hpp index a96cd8f..2aa3f0e 100644 --- a/src/gretl/create_state.hpp +++ b/src/gretl/create_state.hpp @@ -11,7 +11,6 @@ #pragma once #include "data_store.hpp" -#include "upstream_state.hpp" #include namespace gretl { diff --git a/src/gretl/state.hpp b/src/gretl/state.hpp index 68b4ef8..ee78d35 100644 --- a/src/gretl/state.hpp +++ b/src/gretl/state.hpp @@ -11,7 +11,6 @@ #pragma once #include -#include "upstream_state.hpp" #include "state_base.hpp" namespace gretl { diff --git a/src/gretl/state_base.cpp b/src/gretl/state_base.cpp index 1da29da..b1f09e1 100644 --- a/src/gretl/state_base.cpp +++ b/src/gretl/state_base.cpp @@ -5,7 +5,6 @@ // SPDX-License-Identifier: (BSD-3-Clause) #include "state_base.hpp" -#include "upstream_state.hpp" namespace gretl {