Skip to content

Commit 4c13c2a

Browse files
Account->lots is a std::vector<GNCLot*>
1 parent 35ecad8 commit 4c13c2a

File tree

4 files changed

+36
-51
lines changed

4 files changed

+36
-51
lines changed

libgnucash/engine/Account.cpp

+21-37
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ gnc_account_init(Account* acc)
311311
priv->mark = 0;
312312

313313
priv->policy = xaccGetFIFOPolicy();
314-
priv->lots = nullptr;
315314

316315
priv->commodity = nullptr;
317316
priv->commodity_scu = 0;
@@ -327,6 +326,7 @@ gnc_account_init(Account* acc)
327326
priv->starting_reconciled_balance = gnc_numeric_zero();
328327
priv->balance_dirty = FALSE;
329328

329+
new (&priv->lots) LotVec ();
330330
new (&priv->children) AccountVec ();
331331
new (&priv->splits) SplitsVec ();
332332
priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
@@ -1372,7 +1372,6 @@ static void
13721372
xaccFreeAccount (Account *acc)
13731373
{
13741374
AccountPrivate *priv;
1375-
GList *lp;
13761375

13771376
g_return_if_fail(GNC_IS_ACCOUNT(acc));
13781377

@@ -1395,18 +1394,13 @@ xaccFreeAccount (Account *acc)
13951394
}
13961395

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

1403-
for (lp = priv->lots; lp; lp = lp->next)
1404-
{
1405-
GNCLot *lot = static_cast<GNCLot*>(lp->data);
1406-
gnc_lot_destroy (lot);
1407-
}
1408-
g_list_free (priv->lots);
1409-
priv->lots = nullptr;
1402+
std::for_each (priv->lots.rbegin(), priv->lots.rend(), gnc_lot_destroy);
1403+
priv->lots.~LotVec();
14101404
}
14111405

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

15681562
/* the lots should be empty by now */
1569-
for (auto lp = priv->lots; lp; lp = lp->next)
1570-
{
1571-
GNCLot *lot = static_cast<GNCLot*>(lp->data);
1572-
gnc_lot_destroy (lot);
1573-
}
1563+
std::for_each (priv->lots.rbegin(), priv->lots.rend(), gnc_lot_destroy);
15741564
}
1575-
g_list_free(priv->lots);
1576-
priv->lots = nullptr;
1565+
priv->lots.clear(); // this is crucial otherwise test-engine fails
1566+
priv->lots.~LotVec();
15771567

15781568
qof_instance_set_dirty(&acc->inst);
15791569
qof_instance_decrease_editlevel(acc);
@@ -2109,10 +2099,10 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot)
21092099
g_return_if_fail(GNC_IS_LOT(lot));
21102100

21112101
priv = GET_PRIVATE(acc);
2112-
g_return_if_fail(priv->lots);
2102+
g_return_if_fail(!priv->lots.empty());
21132103

21142104
ENTER ("(acc=%p, lot=%p)", acc, lot);
2115-
priv->lots = g_list_remove(priv->lots, lot);
2105+
priv->lots.erase (std::remove (priv->lots.begin(), priv->lots.end(), lot), priv->lots.end());
21162106
qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE, nullptr);
21172107
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, nullptr);
21182108
LEAVE ("(acc=%p, lot=%p)", acc, lot);
@@ -2121,16 +2111,12 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot)
21212111
void
21222112
xaccAccountInsertLot (Account *acc, GNCLot *lot)
21232113
{
2124-
AccountPrivate *priv, *opriv;
2125-
Account * old_acc = nullptr;
2126-
Account* lot_account;
2127-
21282114
/* errors */
21292115
g_return_if_fail(GNC_IS_ACCOUNT(acc));
21302116
g_return_if_fail(GNC_IS_LOT(lot));
21312117

21322118
/* optimizations */
2133-
lot_account = gnc_lot_get_account(lot);
2119+
auto lot_account = gnc_lot_get_account(lot);
21342120
if (lot_account == acc)
21352121
return;
21362122

@@ -2139,13 +2125,12 @@ xaccAccountInsertLot (Account *acc, GNCLot *lot)
21392125
/* pull it out of the old account */
21402126
if (lot_account)
21412127
{
2142-
old_acc = lot_account;
2143-
opriv = GET_PRIVATE(old_acc);
2144-
opriv->lots = g_list_remove(opriv->lots, lot);
2128+
auto& lot_acc_lots = GET_PRIVATE(lot_account)->lots;
2129+
lot_acc_lots.erase (std::remove (lot_acc_lots.begin(), lot_acc_lots.end(), lot),
2130+
lot_acc_lots.end());
21452131
}
21462132

2147-
priv = GET_PRIVATE(acc);
2148-
priv->lots = g_list_prepend(priv->lots, lot);
2133+
GET_PRIVATE(acc)->lots.push_back (lot);
21492134
gnc_lot_set_account(lot, acc);
21502135

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

22222207
/* Finally empty accfrom. */
22232208
g_assert(from_priv->splits.empty());
2224-
g_assert(from_priv->lots == nullptr);
2209+
g_assert(from_priv->lots.empty());
22252210
xaccAccountCommitEdit(accfrom);
22262211
xaccAccountCommitEdit(accto);
22272212

@@ -3918,7 +3903,9 @@ LotList *
39183903
xaccAccountGetLotList (const Account *acc)
39193904
{
39203905
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);
3921-
return g_list_copy(GET_PRIVATE(acc)->lots);
3906+
auto priv = GET_PRIVATE (acc);
3907+
return std::accumulate (priv->lots.rbegin(), priv->lots.rend(),
3908+
static_cast<GList*>(nullptr), g_list_prepend);
39223909
}
39233910

39243911
LotList *
@@ -3928,16 +3915,13 @@ xaccAccountFindOpenLots (const Account *acc,
39283915
gpointer user_data, GCompareFunc sort_func)
39293916
{
39303917
AccountPrivate *priv;
3931-
GList *lot_list;
39323918
GList *retval = nullptr;
39333919

39343920
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);
39353921

39363922
priv = GET_PRIVATE(acc);
3937-
for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
3923+
for (auto lot : priv->lots)
39383924
{
3939-
GNCLot *lot = static_cast<GNCLot*>(lot_list->data);
3940-
39413925
/* If this lot is closed, then ignore it */
39423926
if (gnc_lot_is_closed (lot))
39433927
continue;
@@ -3962,8 +3946,8 @@ xaccAccountForEachLot(const Account *acc,
39623946
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), nullptr);
39633947
g_return_val_if_fail(proc, nullptr);
39643948

3965-
for (auto node = GET_PRIVATE(acc)->lots; node; node = node->next)
3966-
if (auto result = proc(GNC_LOT(node->data), data))
3949+
for (auto lot : GET_PRIVATE(acc)->lots)
3950+
if (auto result = proc(lot, data))
39673951
return result;
39683952

39693953
return nullptr;

libgnucash/engine/Account.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
using SplitsVec = std::vector<Split*>;
4141
using AccountVec = std::vector<Account*>;
42+
using LotVec = std::vector<GNCLot*>;
4243

4344
const SplitsVec& xaccAccountGetSplits (const Account*);
4445

libgnucash/engine/AccountP.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ typedef struct AccountPrivate
119119
GHashTable* splits_hash;
120120
gboolean sort_dirty; /* sort order of splits is bad */
121121

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

125125
char *notes;

libgnucash/engine/test/utest-Account.cpp

+13-13
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ test_xaccFreeAccount (Fixture *fixture, gconstpointer pData)
881881
xaccAccountSetCommodity (parent, commodity);
882882
/* Check that we've got children, lots, and splits to remove */
883883
g_assert_true (!p_priv->children.empty());
884-
g_assert_true (p_priv->lots != NULL);
884+
g_assert_true (!p_priv->lots.empty());
885885
g_assert_true (p_priv->splits.size());
886886
g_assert_true (p_priv->parent != NULL);
887887
g_assert_true (p_priv->commodity != NULL);
@@ -982,7 +982,7 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData)
982982
xaccAccountSetCommodity (parent, commodity);
983983
/* Check that we've got children, lots, and splits to remove */
984984
g_assert_true (!p_priv->children.empty());
985-
g_assert_true (p_priv->lots != NULL);
985+
g_assert_true (!p_priv->lots.empty());
986986
g_assert_true (p_priv->splits.size());
987987
g_assert_true (p_priv->parent != NULL);
988988
g_assert_true (p_priv->commodity != NULL);
@@ -997,7 +997,7 @@ test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData)
997997
test_signal_assert_hits (sig1, 1);
998998
test_signal_assert_hits (sig2, 0);
999999
g_assert_true (!p_priv->children.empty());
1000-
g_assert_true (p_priv->lots != NULL);
1000+
g_assert_true (!p_priv->lots.empty());
10011001
g_assert_true (p_priv->splits.size());
10021002
g_assert_true (p_priv->parent != NULL);
10031003
g_assert_true (p_priv->commodity != NULL);
@@ -1530,24 +1530,24 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
15301530
AccountPrivate *a_priv = fixture->func->get_private (fixture->acct);
15311531
AccountPrivate *p_priv = fixture->func->get_private (parent);
15321532

1533-
g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1534-
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
1533+
g_assert_cmpuint (a_priv->lots.size(), == , 0);
1534+
g_assert_cmpuint (p_priv->lots.size(), == , 0);
15351535
xaccAccountInsertLot (fixture->acct, lot);
15361536
g_assert_true (gnc_lot_get_account (lot) == fixture->acct);
1537-
g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
1537+
g_assert_cmpuint (a_priv->lots.size(), == , 1);
15381538
test_signal_assert_hits (sig1, 1);
15391539
test_signal_assert_hits (sig2, 1);
15401540
/* Make sure that inserting again doesn't do anything */
15411541
xaccAccountInsertLot (fixture->acct, lot);
15421542
g_assert_true (gnc_lot_get_account (lot) == fixture->acct);
1543-
g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
1543+
g_assert_cmpuint (a_priv->lots.size(), == , 1);
15441544
test_signal_assert_hits (sig1, 1);
15451545
test_signal_assert_hits (sig2, 1);
15461546
/* Check that inserting the lot into a different account changes the lot */
15471547
xaccAccountInsertLot (parent, lot);
15481548
g_assert_true (gnc_lot_get_account (lot) == parent);
1549-
g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1550-
g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
1549+
g_assert_cmpuint (a_priv->lots.size(), == , 0);
1550+
g_assert_cmpuint (p_priv->lots.size(), == , 1);
15511551
test_signal_assert_hits (sig1, 2);
15521552
test_signal_assert_hits (sig4, 1);
15531553
test_signal_assert_hits (sig2, 1);
@@ -1557,8 +1557,8 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
15571557
* error in the routine: When removing a lot from an account, the
15581558
* account reference in the lot object should be NULLed. */
15591559
g_assert_true (gnc_lot_get_account (lot) != NULL);
1560-
g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1561-
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
1560+
g_assert_cmpuint (a_priv->lots.size(), == , 0);
1561+
g_assert_cmpuint (p_priv->lots.size(), == , 0);
15621562
test_signal_assert_hits (sig3, 1);
15631563
test_signal_assert_hits (sig4, 2);
15641564
test_signal_assert_hits (sig2, 1);
@@ -1567,11 +1567,11 @@ test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
15671567
* is removed, we have to do that for the next test to work: */
15681568
gnc_lot_set_account (lot, NULL);
15691569
xaccAccountInsertLot (parent, lot);
1570-
g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
1570+
g_assert_cmpuint (p_priv->lots.size(), == , 1);
15711571
g_assert_true (gnc_lot_get_account (lot) == parent);
15721572
gnc_lot_destroy (lot);
15731573
/* Destroying the lot should remove it from the account. */
1574-
g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
1574+
g_assert_cmpuint (p_priv->lots.size(), == , 0);
15751575
test_signal_assert_hits (sig1, 3);
15761576
test_signal_assert_hits (sig3, 2);
15771577
test_signal_assert_hits (sig4, 4);

0 commit comments

Comments
 (0)