From 04e3869fa890d04a51d326e5fb35f941c55d4cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 21 Nov 2023 13:48:42 +0100 Subject: [PATCH 1/5] Upgrade nixpkgs --- shell.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell.nix b/shell.nix index 749bdbb8..0887f9a9 100644 --- a/shell.nix +++ b/shell.nix @@ -1,7 +1,7 @@ { compiler ? "", - rev ? "f904e3562aabca382d12f8471ca2330b3f82899a", - sha256 ? "1lsa3sjwp1v3nv2jjpkl5lf9dncplwihmavasalg9fq1217pmzmb", + rev ? "4ed9856be002a730234a1a1ed9dcd9dd10cbdb40", + sha256 ? "1jbw1qayzmx1720nm6qkvs6q0rmndf9qjk1qq5p67qzlyfdmjb8f", nixpkgs ? builtins.fetchTarball { name = "nixpkgs-${rev}"; url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz"; From 231f52403b0bfecd91c7fed7a22208751e3836db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 21 Nov 2023 13:49:07 +0100 Subject: [PATCH 2/5] Add missing LAGER_THROW --- lager/reader.hpp | 14 +++++++++----- lager/writer.hpp | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lager/reader.hpp b/lager/reader.hpp index 8744bf65..28a3c800 100644 --- a/lager/reader.hpp +++ b/lager/reader.hpp @@ -71,10 +71,11 @@ struct reader_mixin auto node_() const { - if(auto node = detail::access::node(*static_cast(this))) { + if (auto node = + detail::access::node(*static_cast(this))) { return node; } - throw std::runtime_error("Accessing uninitialized reader"); + LAGER_THROW(std::runtime_error("Accessing uninitialized reader")); } }; @@ -101,7 +102,8 @@ class reader_base int> = 0> reader_base(reader_base x) : base_t{std::move(x)} - {} + { + } template , @@ -109,12 +111,14 @@ class reader_base int> = 0> reader_base(cursor_base x) : base_t{std::move(x)} - {} + { + } template reader_base(std::shared_ptr n) : base_t{std::move(n)} - {} + { + } }; /*! diff --git a/lager/writer.hpp b/lager/writer.hpp index f8ed2205..93dd54e7 100644 --- a/lager/writer.hpp +++ b/lager/writer.hpp @@ -70,10 +70,11 @@ struct writer_mixin auto node_() const { - if(auto node = detail::access::node(*static_cast(this))) { + if (auto node = + detail::access::node(*static_cast(this))) { return node; } - throw std::runtime_error("Accessing uninitialized writer"); + LAGER_THROW(std::runtime_error("Accessing uninitialized writer")); } }; @@ -100,16 +101,19 @@ class writer_base template writer_base(writer_base x) : node_(std::move(x.node_)) - {} + { + } template writer_base(cursor_base x) : node_(detail::access::node(std::move(x))) - {} + { + } writer_base(node_ptr_t sig) : node_(std::move(sig)) - {} + { + } }; /*! From 46344ac6557ce2a524bc134f6fe7be73d704f53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 21 Nov 2023 13:49:31 +0100 Subject: [PATCH 3/5] Make lenses work when no exception support is enabled --- lager/lenses/at.hpp | 63 ++++++++++++++++++++++++++++++++---------- lager/lenses/at_or.hpp | 36 +++++++++++++----------- 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/lager/lenses/at.hpp b/lager/lenses/at.hpp index 22e3d31f..9e4bbdf8 100644 --- a/lager/lenses/at.hpp +++ b/lager/lenses/at.hpp @@ -24,20 +24,51 @@ template using insert_opt_t = std::decay_t().insert( std::declval().value()))>; +template +using has_count_t = decltype(std::declval().count(std::declval())); + +// When building without exception support, returns whether the container has +// the key, using some heuristics to distinguish vector-likes or map-like +// containers. Otherwise it just returns true and we use the normal +// exception-based mechanism. +template +bool maybe_has_key(const Whole& whole, const Key& k) noexcept +{ +#ifdef LAGER_NO_EXCEPTIONS + if constexpr (zug::meta::is_detected::value) { + return whole.count(k) > 0; + } else if constexpr (std::is_convertible:: + value) { + const auto k_ = static_cast(k); + return k_ >= typename Whole::size_type{} && k_ < whole.size(); + } else { + static_assert( + zug::meta::is_detected::value || + std::is_convertible::value, + "at lense not supported with LAGER_NO_EXCEPTIONS"); + return true; + } +#else + return true; +#endif +} + template ::value && - !zug::meta::is_detected::value, + !zug::meta::is_detected::value, int> = 0> std::decay_t at_setter_impl(Whole&& whole, Part&& part, Key&& key) { auto r = std::forward(whole); - if (part.has_value()) { - LAGER_TRY { + if (maybe_has_key(r, key) && part.has_value()) { + LAGER_TRY + { r.at(std::forward(key)) = std::forward(part).value(); - } LAGER_CATCH(std::out_of_range const&) {} + } + LAGER_CATCH(std::out_of_range const&) {} } return r; } @@ -50,12 +81,14 @@ template < int> = 0> std::decay_t at_setter_impl(Whole&& whole, Part&& part, Key&& key) { - if (part.has_value()) { - LAGER_TRY { + if (maybe_has_key(whole, key) && part.has_value()) { + LAGER_TRY + { (void) whole.at(std::forward(key)); return std::forward(whole).set( std::forward(key), std::forward(part).value()); - } LAGER_CATCH(std::out_of_range const&) {} + } + LAGER_CATCH(std::out_of_range const&) {} } return std::forward(whole); } @@ -69,9 +102,12 @@ template < std::decay_t at_setter_impl(Whole&& whole, Part&& part, Key&& key) { if (part.has_value()) { - LAGER_TRY { - return std::forward(whole).insert(std::forward(part).value()); - } LAGER_CATCH(std::out_of_range const&) {} + LAGER_TRY + { + return std::forward(whole).insert( + std::forward(part).value()); + } + LAGER_CATCH(std::out_of_range const&) {} } return std::forward(whole); } @@ -91,11 +127,10 @@ auto at(Key key) return [f = LAGER_FWD(f), &key](auto&& whole) { using Part = std::optional>; return f([&]() -> Part { - LAGER_TRY { - return LAGER_FWD(whole).at(key); - } LAGER_CATCH(std::out_of_range const&) { + if (!detail::maybe_has_key(whole, key)) return std::nullopt; - } + LAGER_TRY { return LAGER_FWD(whole).at(key); } + LAGER_CATCH(std::out_of_range const&) { return std::nullopt; } }())([&](Part part) { return detail::at_setter_impl( LAGER_FWD(whole), std::move(part), key); diff --git a/lager/lenses/at_or.hpp b/lager/lenses/at_or.hpp index 5f356086..04b58db3 100644 --- a/lager/lenses/at_or.hpp +++ b/lager/lenses/at_or.hpp @@ -1,12 +1,13 @@ #pragma once +#include + #include #include #include #include -#include #include #include @@ -16,8 +17,8 @@ namespace detail { // detect if T satifsies the immer API for setting values template -using set_t = std::decay_t().set(std::declval(), std::declval()))>; +using set_t = std::decay_t().set(std::declval(), + std::declval()))>; template < typename Whole, @@ -27,10 +28,11 @@ template < int> = 0> std::decay_t at_or_setter_impl(Whole&& whole, Part&& part, Key&& key) { + if (!maybe_has_key(whole, key)) + return std::forward(whole); auto r = std::forward(whole); - LAGER_TRY { - r.at(std::forward(key)) = std::forward(part); - } LAGER_CATCH(std::out_of_range const&) {} + LAGER_TRY { r.at(std::forward(key)) = std::forward(part); } + LAGER_CATCH(std::out_of_range const&) {} return r; } @@ -42,11 +44,15 @@ template < int> = 0> std::decay_t at_or_setter_impl(Whole&& whole, Part&& part, Key&& key) { - LAGER_TRY { + if (!maybe_has_key(whole, key)) + return std::forward(whole); + LAGER_TRY + { (void) whole.at(std::forward(key)); return std::forward(whole).set(std::forward(key), std::forward(part)); - } LAGER_CATCH(std::out_of_range const&) {} + } + LAGER_CATCH(std::out_of_range const&) {} return std::forward(whole); } @@ -62,11 +68,10 @@ auto at_or(Key key) return [f = LAGER_FWD(f), &key](auto&& whole) { using Part = std::decay_t; return f([&]() -> Part { - LAGER_TRY { - return LAGER_FWD(whole).at(key); - } LAGER_CATCH(std::out_of_range const&) { + if (!detail::maybe_has_key(whole, key)) return Part{}; - } + LAGER_TRY { return LAGER_FWD(whole).at(key); } + LAGER_CATCH(std::out_of_range const&) { return Part{}; } }())([&](auto&& part) { return detail::at_or_setter_impl( LAGER_FWD(whole), LAGER_FWD(part), key); @@ -85,11 +90,10 @@ auto at_or(Key key, Default&& def) return [f = LAGER_FWD(f), &key, &def](auto&& whole) { using Part = std::decay_t; return f([&]() -> Part { - LAGER_TRY { - return LAGER_FWD(whole).at(key); - } LAGER_CATCH(std::out_of_range const&) { + if (!detail::maybe_has_key(whole, key)) return def; - } + LAGER_TRY { return LAGER_FWD(whole).at(key); } + LAGER_CATCH(std::out_of_range const&) { return def; } }())([&](auto&& part) { return detail::at_or_setter_impl( LAGER_FWD(whole), LAGER_FWD(part), key); From 687746c9d09956ce0ddffab932ef5c70e9f00ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 21 Nov 2023 13:51:05 +0100 Subject: [PATCH 4/5] Upgrade dependency syntax --- default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.nix b/default.nix index 78a758cd..41a1a384 100644 --- a/default.nix +++ b/default.nix @@ -22,7 +22,7 @@ stdenv.mkDerivation rec { cmake gcc7 sass - pkgconfig + pkgs.pkg-config or pkgs.pkgconfig ]; cmakeFlags = [ "-Dlager_BUILD_TESTS=OFF" From 539ca376363b107b873db2eb02fe64e874c9f1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pedro=20Bol=C3=ADvar=20Puente?= Date: Tue, 21 Nov 2023 15:13:43 +0100 Subject: [PATCH 5/5] Revert "Upgrade nixpkgs" This reverts commit 04e3869fa890d04a51d326e5fb35f941c55d4cb5. --- shell.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell.nix b/shell.nix index 0887f9a9..749bdbb8 100644 --- a/shell.nix +++ b/shell.nix @@ -1,7 +1,7 @@ { compiler ? "", - rev ? "4ed9856be002a730234a1a1ed9dcd9dd10cbdb40", - sha256 ? "1jbw1qayzmx1720nm6qkvs6q0rmndf9qjk1qq5p67qzlyfdmjb8f", + rev ? "f904e3562aabca382d12f8471ca2330b3f82899a", + sha256 ? "1lsa3sjwp1v3nv2jjpkl5lf9dncplwihmavasalg9fq1217pmzmb", nixpkgs ? builtins.fetchTarball { name = "nixpkgs-${rev}"; url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz";