diff --git a/src/lazy_optional.h b/src/lazy_optional.h new file mode 100644 index 0000000..ddfd801 --- /dev/null +++ b/src/lazy_optional.h @@ -0,0 +1,45 @@ +// Copyright (C) 2024 Simon Quigley +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef LAZY_OPTIONAL_H +#define LAZY_OPTIONAL_H + +#include +#include + +template +class lazy_optional { +public: + lazy_optional(Loader loader) : loader_(std::move(loader)) {} + + T& operator*() { load(); return *value_; } + const T& operator*() const { load(); return *value_; } + + T* operator->() { load(); return &*value_; } + const T* operator->() const { load(); return &*value_; } + + explicit operator bool() const { load(); return value_.has_value(); } + +private: + mutable std::optional value_; + [[no_unique_address]] Loader loader_; + + // Removed constexpr + void load() const { + if (!value_) value_ = loader_(); + } +}; + +#endif // LAZY_OPTIONAL_H diff --git a/src/source_package_publishing_history.cpp b/src/source_package_publishing_history.cpp index 5cc2023..b71af24 100644 --- a/src/source_package_publishing_history.cpp +++ b/src/source_package_publishing_history.cpp @@ -21,7 +21,27 @@ #include source_package_publishing_history::source_package_publishing_history() - : source_package_name(""), source_package_version(""), self_link(""), lp(nullptr) {} + : source_package_name(""), + source_package_version(""), + self_link(""), + lp(nullptr), + distro_series([this]() -> std::optional { + if (distro_series_link.empty()) return std::nullopt; + + auto response = lp ? lp->api_get(distro_series_link) : std::nullopt; + if (!response) return std::nullopt; + + auto data = nlohmann::json::parse(response.value()); + auto ds = distro_series::parse(data.dump()); + + if (ds) { + ds->set_lp(lp); + return ds; + } + + return std::nullopt; + }) +{} source_package_publishing_history::~source_package_publishing_history() {} @@ -81,19 +101,6 @@ void source_package_publishing_history::set_lp(launchpad* lp_ptr) { lp = lp_ptr; } -const std::optional source_package_publishing_history::getDistroSeries() { - if (distro_series_link.empty()) return std::nullopt; - auto response = lp->api_get(distro_series_link); - if (!response) return std::nullopt; - auto data = nlohmann::json::parse(response.value()); - auto ds = distro_series::parse(data.dump()); - if (ds) { - ds->set_lp(lp); - return ds; - } - return std::nullopt; -} - std::generator source_package_publishing_history::getPublishedBinaries(bool active_binaries_only) const { std::map params; params["ws.op"] = "getPublishedBinaries"; diff --git a/src/source_package_publishing_history.h b/src/source_package_publishing_history.h index cf3c418..6a1ae9d 100644 --- a/src/source_package_publishing_history.h +++ b/src/source_package_publishing_history.h @@ -20,6 +20,7 @@ #include #include #include "distro_series.h" +#include "lazy_optional.h" class launchpad; class build; @@ -42,7 +43,7 @@ public: void parse_json(const std::string& json_data); std::generator getBuilds() const; - std::optional distro_series = getDistroSeries(); + lazy_optional()>> distro_series; std::generator getPublishedBinaries(bool active_binaries_only = false) const; bool requestDeletion(const std::string& removal_comment = ""); @@ -56,7 +57,6 @@ public: private: launchpad* lp; - const std::optional getDistroSeries(); }; #endif // SOURCE_PACKAGE_PUBLISHING_HISTORY