Skip to content
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

Account->lots is a std::vector<GNCLot*> #2041

Draft
wants to merge 1 commit into
base: stable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 21 additions & 37 deletions libgnucash/engine/Account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ gnc_account_init(Account* acc)
priv->mark = 0;

priv->policy = xaccGetFIFOPolicy();
priv->lots = nullptr;

priv->commodity = nullptr;
priv->commodity_scu = 0;
Expand All @@ -327,6 +326,7 @@ gnc_account_init(Account* acc)
priv->starting_reconciled_balance = gnc_numeric_zero();
priv->balance_dirty = FALSE;

new (&priv->lots) LotVec ();
new (&priv->children) AccountVec ();
new (&priv->splits) SplitsVec ();
priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
Expand Down Expand Up @@ -1372,7 +1372,6 @@ static void
xaccFreeAccount (Account *acc)
{
AccountPrivate *priv;
GList *lp;

g_return_if_fail(GNC_IS_ACCOUNT(acc));

Expand All @@ -1395,18 +1394,13 @@ xaccFreeAccount (Account *acc)
}

/* remove lots -- although these should be gone by now. */
if (priv->lots)
if (!priv->lots.empty())
{
PERR (" instead of calling xaccFreeAccount(), please call\n"
" xaccAccountBeginEdit(); xaccAccountDestroy();\n");

for (lp = priv->lots; lp; lp = lp->next)
{
GNCLot *lot = static_cast<GNCLot*>(lp->data);
gnc_lot_destroy (lot);
}
g_list_free (priv->lots);
priv->lots = nullptr;
std::for_each (priv->lots.rbegin(), priv->lots.rend(), gnc_lot_destroy);
priv->lots.~LotVec();
}

/* Next, clean up the splits */
Expand Down Expand Up @@ -1566,14 +1560,10 @@ xaccAccountCommitEdit (Account *acc)
qof_collection_foreach(col, destroy_pending_splits_for_account, acc);

/* the lots should be empty by now */
for (auto lp = priv->lots; lp; lp = lp->next)
{
GNCLot *lot = static_cast<GNCLot*>(lp->data);
gnc_lot_destroy (lot);
}
std::for_each (priv->lots.rbegin(), priv->lots.rend(), gnc_lot_destroy);
}
g_list_free(priv->lots);
priv->lots = nullptr;
priv->lots.clear(); // this is crucial otherwise test-engine fails
priv->lots.~LotVec();

qof_instance_set_dirty(&acc->inst);
qof_instance_decrease_editlevel(acc);
Expand Down Expand Up @@ -2109,10 +2099,10 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot)
g_return_if_fail(GNC_IS_LOT(lot));

priv = GET_PRIVATE(acc);
g_return_if_fail(priv->lots);
g_return_if_fail(!priv->lots.empty());

ENTER ("(acc=%p, lot=%p)", acc, lot);
priv->lots = g_list_remove(priv->lots, lot);
priv->lots.erase (std::remove (priv->lots.begin(), priv->lots.end(), lot), priv->lots.end());
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE, nullptr);
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, nullptr);
LEAVE ("(acc=%p, lot=%p)", acc, lot);
Expand All @@ -2121,16 +2111,12 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot)
void
xaccAccountInsertLot (Account *acc, GNCLot *lot)
{
AccountPrivate *priv, *opriv;
Account * old_acc = nullptr;
Account* lot_account;

/* errors */
g_return_if_fail(GNC_IS_ACCOUNT(acc));
g_return_if_fail(GNC_IS_LOT(lot));

/* optimizations */
lot_account = gnc_lot_get_account(lot);
auto lot_account = gnc_lot_get_account(lot);
if (lot_account == acc)
return;

Expand All @@ -2139,13 +2125,12 @@ xaccAccountInsertLot (Account *acc, GNCLot *lot)
/* pull it out of the old account */
if (lot_account)
{
old_acc = lot_account;
opriv = GET_PRIVATE(old_acc);
opriv->lots = g_list_remove(opriv->lots, lot);
auto& lot_acc_lots = GET_PRIVATE(lot_account)->lots;
lot_acc_lots.erase (std::remove (lot_acc_lots.begin(), lot_acc_lots.end(), lot),
lot_acc_lots.end());
}

priv = GET_PRIVATE(acc);
priv->lots = g_list_prepend(priv->lots, lot);
GET_PRIVATE(acc)->lots.push_back (lot);
gnc_lot_set_account(lot, acc);

/* Don't move the splits to the new account. The caller will do this
Expand Down Expand Up @@ -2221,7 +2206,7 @@ xaccAccountMoveAllSplits (Account *accfrom, Account *accto)

/* Finally empty accfrom. */
g_assert(from_priv->splits.empty());
g_assert(from_priv->lots == nullptr);
g_assert(from_priv->lots.empty());
xaccAccountCommitEdit(accfrom);
xaccAccountCommitEdit(accto);

Expand Down Expand Up @@ -3918,7 +3903,9 @@ LotList *
xaccAccountGetLotList (const Account *acc)
{
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);
return g_list_copy(GET_PRIVATE(acc)->lots);
auto priv = GET_PRIVATE (acc);
return std::accumulate (priv->lots.rbegin(), priv->lots.rend(),
static_cast<GList*>(nullptr), g_list_prepend);
}

LotList *
Expand All @@ -3928,16 +3915,13 @@ xaccAccountFindOpenLots (const Account *acc,
gpointer user_data, GCompareFunc sort_func)
{
AccountPrivate *priv;
GList *lot_list;
GList *retval = nullptr;

g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);

priv = GET_PRIVATE(acc);
for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
for (auto lot : priv->lots)
{
GNCLot *lot = static_cast<GNCLot*>(lot_list->data);

/* If this lot is closed, then ignore it */
if (gnc_lot_is_closed (lot))
continue;
Expand All @@ -3962,8 +3946,8 @@ xaccAccountForEachLot(const Account *acc,
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);
g_return_val_if_fail(proc, nullptr);

for (auto node = GET_PRIVATE(acc)->lots; node; node = node->next)
if (auto result = proc(GNC_LOT(node->data), data))
for (auto lot : GET_PRIVATE(acc)->lots)
if (auto result = proc(lot, data))
return result;

return nullptr;
Expand Down
1 change: 1 addition & 0 deletions libgnucash/engine/Account.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

using SplitsVec = std::vector<Split*>;
using AccountVec = std::vector<Account*>;
using LotVec = std::vector<GNCLot*>;

const SplitsVec& xaccAccountGetSplits (const Account*);

Expand Down
2 changes: 1 addition & 1 deletion libgnucash/engine/AccountP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ typedef struct AccountPrivate
GHashTable* splits_hash;
gboolean sort_dirty; /* sort order of splits is bad */

LotList *lots; /* list of lot pointers */
std::vector<GNCLot*> lots; /* list of lot pointers */
GNCPolicy *policy; /* Cached pointer to policy method */

char *notes;
Expand Down
26 changes: 13 additions & 13 deletions libgnucash/engine/test/utest-Account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData)
xaccAccountSetCommodity (parent, commodity);
/* Check that we've got children, lots, and splits to remove */
g_assert_true (!p_priv->children.empty());
g_assert_true (p_priv->lots != NULL);
g_assert_true (!p_priv->lots.empty());
g_assert_true (p_priv->splits.size());
g_assert_true (p_priv->parent != NULL);
g_assert_true (p_priv->commodity != NULL);
Expand Down Expand Up @@ -982,7 +982,7 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData)
xaccAccountSetCommodity (parent, commodity);
/* Check that we've got children, lots, and splits to remove */
g_assert_true (!p_priv->children.empty());
g_assert_true (p_priv->lots != NULL);
g_assert_true (!p_priv->lots.empty());
g_assert_true (p_priv->splits.size());
g_assert_true (p_priv->parent != NULL);
g_assert_true (p_priv->commodity != NULL);
Expand All @@ -997,7 +997,7 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData)
test_signal_assert_hits (sig1, 1);
test_signal_assert_hits (sig2, 0);
g_assert_true (!p_priv->children.empty());
g_assert_true (p_priv->lots != NULL);
g_assert_true (!p_priv->lots.empty());
g_assert_true (p_priv->splits.size());
g_assert_true (p_priv->parent != NULL);
g_assert_true (p_priv->commodity != NULL);
Expand Down Expand Up @@ -1530,24 +1530,24 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
AccountPrivate *a_priv = fixture->func->get_private (fixture->acct);
AccountPrivate *p_priv = fixture->func->get_private (parent);

g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
g_assert_cmpuint (a_priv->lots.size(), == , 0);
g_assert_cmpuint (p_priv->lots.size(), == , 0);
xaccAccountInsertLot (fixture->acct, lot);
g_assert_true (gnc_lot_get_account (lot) == fixture->acct);
g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
g_assert_cmpuint (a_priv->lots.size(), == , 1);
test_signal_assert_hits (sig1, 1);
test_signal_assert_hits (sig2, 1);
/* Make sure that inserting again doesn't do anything */
xaccAccountInsertLot (fixture->acct, lot);
g_assert_true (gnc_lot_get_account (lot) == fixture->acct);
g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
g_assert_cmpuint (a_priv->lots.size(), == , 1);
test_signal_assert_hits (sig1, 1);
test_signal_assert_hits (sig2, 1);
/* Check that inserting the lot into a different account changes the lot */
xaccAccountInsertLot (parent, lot);
g_assert_true (gnc_lot_get_account (lot) == parent);
g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
g_assert_cmpuint (a_priv->lots.size(), == , 0);
g_assert_cmpuint (p_priv->lots.size(), == , 1);
test_signal_assert_hits (sig1, 2);
test_signal_assert_hits (sig4, 1);
test_signal_assert_hits (sig2, 1);
Expand All @@ -1557,8 +1557,8 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
* error in the routine: When removing a lot from an account, the
* account reference in the lot object should be NULLed. */
g_assert_true (gnc_lot_get_account (lot) != NULL);
g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
g_assert_cmpuint (a_priv->lots.size(), == , 0);
g_assert_cmpuint (p_priv->lots.size(), == , 0);
test_signal_assert_hits (sig3, 1);
test_signal_assert_hits (sig4, 2);
test_signal_assert_hits (sig2, 1);
Expand All @@ -1567,11 +1567,11 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
* is removed, we have to do that for the next test to work: */
gnc_lot_set_account (lot, NULL);
xaccAccountInsertLot (parent, lot);
g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
g_assert_cmpuint (p_priv->lots.size(), == , 1);
g_assert_true (gnc_lot_get_account (lot) == parent);
gnc_lot_destroy (lot);
/* Destroying the lot should remove it from the account. */
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
g_assert_cmpuint (p_priv->lots.size(), == , 0);
test_signal_assert_hits (sig1, 3);
test_signal_assert_hits (sig3, 2);
test_signal_assert_hits (sig4, 4);
Expand Down