gnucash stable: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Sat Sep 26 14:20:13 EDT 2026


Updated	 via  https://github.com/Gnucash/gnucash/commit/7755418c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5ed56e2b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/5888a04a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3bbf74a7 (commit)
	from  https://github.com/Gnucash/gnucash/commit/d8f0e151 (commit)



commit 7755418cb80ff8195ca3918018e6d08244638dfc
Merge: d8f0e151a7 5ed56e2b3d
Author: John Ralls <jralls at ceridwen.us>
Date:   Sat Sep 26 11:19:33 2026 -0700

    Merge Chris Lam's 'acc-templated-split-iterator' into stable.


commit 5ed56e2b3de39c839c1c5552b500fdda459e5d16
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Sep 26 20:41:26 2026 +0800

    [engine.i] use gnc_account_foreach_split_between_dates
    
    avoids calling callback on splits before start_date

diff --git a/bindings/engine.i b/bindings/engine.i
index 2c42daec20..862d7f672b 100644
--- a/bindings/engine.i
+++ b/bindings/engine.i
@@ -168,6 +168,8 @@ SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date
                                           time64 end_date, gnc_commodity *comm, bool sort)
 {
     SplitsVec rv;
+    std::optional<time64> end;
+    if (use_end_date) end = end_date;
 
     auto maybe_accumulate = [&rv, comm](auto s)
     {
@@ -179,15 +181,12 @@ SplitsVec gnc_get_match_commodity_splits (AccountVec accounts, bool use_end_date
             rv.push_back (s);
     };
 
-    std::function<void(Account*)> scan_account;
-    if (use_end_date)
-        scan_account = [end_date, maybe_accumulate](auto acc)
-            { gnc_account_foreach_split_until_date (acc, end_date, maybe_accumulate); };
-    else
-        scan_account = [maybe_accumulate](auto acc)
-            { gnc_account_foreach_split (acc, maybe_accumulate); };
+    std::for_each (accounts.begin(), accounts.end(), [&](auto acc)
+                   {
+                       gnc_account_foreach_split_between_dates (acc, {}, end, false,
+                                                                maybe_accumulate);
+                   });
 
-    std::for_each (accounts.begin(), accounts.end(), scan_account);
     if (sort)
         std::sort (rv.begin(), rv.end(), [](auto a, auto b){ return xaccSplitOrder (a, b) < 0; });
     return rv;
@@ -257,26 +256,14 @@ gnc_accounts_and_all_descendants (AccountVec accounts)
 void
 gnc_account_foreach_split_between_dates (const Account* account,
                                          SCM start_date, SCM end_date,
-                                         bool include_children, SCM scm_cb)
+                                         bool incl_descendants, SCM scm_cb)
 {
     std::optional<time64> start, end;
     if (scm_is_exact_integer (start_date)) start = scm_to_int64 (start_date);
     if (scm_is_exact_integer (end_date))   end = scm_to_int64 (end_date);
-    auto maybe_call = [&](const Split* s)
-    {
-        if (!start || *start <= xaccTransGetDate (xaccSplitGetParent (s)))
-            scm_call_1 (scm_cb, gnc_split_to_scm (s));
-    };
-    std::function<void(const Account*)> scan_account;
-    if (end)
-        scan_account = [end, maybe_call](auto acc)
-            { gnc_account_foreach_split_until_date (acc, *end, maybe_call); };
-    else
-        scan_account = [maybe_call](auto acc)
-            { gnc_account_foreach_split (acc, maybe_call); };
-    scan_account (account);
-    if (include_children)
-        gnc_account_foreach_descendant (account, scan_account);
+
+    auto cb = [&](auto s) { scm_call_1 (scm_cb, gnc_split_to_scm (s)); };
+    gnc_account_foreach_split_between_dates (account, start, end, incl_descendants, cb);
 }
 
 %}

commit 5888a04a8e9c89a6e6b66eb270d17ede456202d5
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Sep 26 20:41:17 2026 +0800

    [account.cpp] use gnc_account_foreach_split_between_dates

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 612fbd7832..89f849386b 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -1140,26 +1140,14 @@ xaccInitAccount (Account * acc, QofBook *book)
 void
 gnc_account_foreach_split (const Account *acc, std::function<void(Split*)> func)
 {
-    if (!GNC_IS_ACCOUNT (acc))
-        return;
-
-    auto& splits{GET_PRIVATE(acc)->splits};
-    std::for_each (splits.begin(), splits.end(), func);
+    gnc_account_foreach_split_between_dates (acc, {}, {}, false, func);
 }
 
 void
 gnc_account_foreach_split_until_date (const Account *acc, time64 end_date,
                                       std::function<void(Split*)> f)
 {
-    if (!GNC_IS_ACCOUNT (acc))
-        return;
-
-    auto after_date = [](time64 end_date, auto s) -> bool
-    { return (xaccTransGetDate (xaccSplitGetParent (s)) > end_date); };
-
-    auto& splits{GET_PRIVATE(acc)->splits};
-    auto after_date_iter = std::upper_bound (splits.begin(), splits.end(), end_date, after_date);
-    std::for_each (splits.begin(), after_date_iter, f);
+    gnc_account_foreach_split_between_dates (acc, {}, end_date, false, f);
 }
 
 

commit 3bbf74a7306698533c3b1b278362089f41f5e5df
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Sep 26 20:40:03 2026 +0800

    [account.hpp] introduce gnc_account_foreach_split_between_dates
    
    A templated account->splits iterator, will target splits from
    start_date to end_date, inclusive of date boundaries. Also optionally
    include descendants.

diff --git a/libgnucash/engine/Account.hpp b/libgnucash/engine/Account.hpp
index 9049cb94b7..dbc88a3f0b 100644
--- a/libgnucash/engine/Account.hpp
+++ b/libgnucash/engine/Account.hpp
@@ -34,8 +34,12 @@
 
 #include <vector>
 #include <functional>
+#include <algorithm>
+#include <optional>
 
 #include <Account.h>
+#include <SplitP.hpp>
+#include <TransactionP.hpp>
 
 using SplitsVec = std::vector<Split*>;
 using AccountVec = std::vector<Account*>;
@@ -44,6 +48,42 @@ const SplitsVec& xaccAccountGetSplits (const Account*);
 
 void gnc_account_foreach_descendant (const Account *, std::function<void(Account*)> func);
 
+
+static inline SplitsVec::const_iterator
+splits_start (const SplitsVec& splits, std::optional<time64> start_date)
+{
+    if (!start_date) return splits.begin();
+    return std::lower_bound (splits.begin(), splits.end(), *start_date,
+                             [](auto s, time64 t){ return s->parent->date_posted < t; });
+}
+
+static inline SplitsVec::const_iterator
+splits_end (const SplitsVec& splits, std::optional<time64> end_date)
+{
+    if (!end_date) return splits.end();
+    return std::upper_bound (splits.begin(), splits.end(), *end_date,
+                             [](time64 t, auto s){ return t < s->parent->date_posted; });
+}
+
+template <typename Fn>
+void gnc_account_foreach_split_between_dates (const Account* account,
+                                              std::optional<time64> start_date,
+                                              std::optional<time64> end_date,
+                                              bool include_descendants, Fn&& fn)
+{
+    g_return_if_fail (GNC_IS_ACCOUNT (account));
+    auto scan_account = [&](const Account* acc)
+    {
+        const auto& splits = xaccAccountGetSplits (acc);
+        std::for_each (splits_start (splits, start_date), splits_end (splits, end_date),
+                       fn);
+    };
+
+    scan_account (account);
+    if (include_descendants)
+        gnc_account_foreach_descendant (account, scan_account);
+}
+
 void gnc_account_foreach_split (const Account*, std::function<void(Split*)>);
 
 void gnc_account_foreach_split_until_date (const Account *acc, time64 end_date,



Summary of changes:
 bindings/engine.i             | 35 +++++++++++------------------------
 libgnucash/engine/Account.cpp | 16 ++--------------
 libgnucash/engine/Account.hpp | 40 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 38 deletions(-)



More information about the gnucash-changes mailing list