From 41a6cd1d6ca2f121d6b95dfd72386d29845aa804 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 09:31:32 +0000 Subject: [PATCH 01/11] Remove commented-out obsolete code --- src/gui/gamedoc.cc | 38 -------------------------------------- src/gui/gamedoc.h | 7 ------- 2 files changed, 45 deletions(-) diff --git a/src/gui/gamedoc.cc b/src/gui/gamedoc.cc index 4f493a6ef..06b3fdf5b 100644 --- a/src/gui/gamedoc.cc +++ b/src/gui/gamedoc.cc @@ -338,44 +338,6 @@ void GameDocument::SetProfileList(int p_index) UpdateViews(GBT_DOC_MODIFIED_VIEWS); } -/* -void GameDocument::AddProfiles(const List > -&p_profiles) -{ - for (int i = 1; i <= p_profiles.Length(); i++) { - m_profiles[m_currentProfileList].Append(p_profiles[i]); - } - - m_profiles[m_currentProfileList].SetCurrent(m_profiles[m_currentProfileList].NumProfiles()); - UpdateViews(GBT_DOC_MODIFIED_VIEWS); -} - -void GameDocument::AddProfile(const MixedBehavProfile &p_profile) -{ - m_profiles[m_currentProfileList].Append(p_profile); - m_profiles[m_currentProfileList].SetCurrent(m_profiles[m_currentProfileList].NumProfiles()); - UpdateViews(GBT_DOC_MODIFIED_VIEWS); -} - -void GameDocument::AddProfiles(const List > -&p_profiles) -{ - for (int i = 1; i <= p_profiles.Length(); i++) { - m_profiles[m_currentProfileList].Append(p_profiles[i]); - } - - m_profiles[m_currentProfileList].SetCurrent(m_profiles[m_currentProfileList].NumProfiles()); - UpdateViews(GBT_DOC_MODIFIED_VIEWS); -} - -void GameDocument::AddProfile(const MixedStrategyProfile &p_profile) -{ - m_profiles[m_currentProfileList].Append(p_profile); - m_profiles[m_currentProfileList].SetCurrent(m_profiles[m_currentProfileList].NumProfiles()); - UpdateViews(GBT_DOC_MODIFIED_VIEWS); -} -*/ - void GameDocument::SetStrategyElimStrength(bool p_strict) { m_stratSupports.SetStrict(p_strict); diff --git a/src/gui/gamedoc.h b/src/gui/gamedoc.h index 0701d6dcf..d13a083f6 100644 --- a/src/gui/gamedoc.h +++ b/src/gui/gamedoc.h @@ -210,13 +210,6 @@ class GameDocument { return (m_profiles.size() == 0) ? 0 : GetProfiles().GetCurrent(); } void SetCurrentProfile(int p_profile); - /* - void AddProfiles(const List > &); - void AddProfile(const MixedBehavProfile &); - void AddProfiles(const List > &); - void AddProfile(const MixedStrategyProfile &); - */ - //@} //! //! @name Handling of behavior supports From a0efe103cb4c27f6227755bbd97ac2f97e5ff442 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 09:40:07 +0000 Subject: [PATCH 02/11] Replace List with Array in enummixed --- src/solvers/enummixed/clique.h | 6 +++--- src/solvers/enummixed/enummixed.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/solvers/enummixed/clique.h b/src/solvers/enummixed/clique.h index 2b1939c31..5de7a68f2 100644 --- a/src/solvers/enummixed/clique.h +++ b/src/solvers/enummixed/clique.h @@ -211,13 +211,13 @@ class CliqueEnumerator { CliqueEnumerator(Array &, int, int); ~CliqueEnumerator() = default; - const List> &GetCliques1() const { return m_cliques1; } - const List> &GetCliques2() const { return m_cliques2; } + const Array> &GetCliques1() const { return m_cliques1; } + const Array> &GetCliques2() const { return m_cliques2; } private: Array firstedge; int maxinp1, maxinp2; - List> m_cliques1, m_cliques2; + Array> m_cliques1, m_cliques2; void candtry1(int stk[], // stack bool connected[MAXM][MAXN], diff --git a/src/solvers/enummixed/enummixed.h b/src/solvers/enummixed/enummixed.h index 22d0fd201..c35700dfa 100644 --- a/src/solvers/enummixed/enummixed.h +++ b/src/solvers/enummixed/enummixed.h @@ -51,14 +51,14 @@ template class EnumMixedStrategySolution { /// Representation of the graph connecting the extreme equilibria ///@{ - List> m_key1, m_key2; - List m_node1, m_node2; // IDs of each component of the extreme equilibria + Array> m_key1, m_key2; + Array m_node1, m_node2; // IDs of each component of the extreme equilibria int m_v1{0}, m_v2{0}; ///@} /// Representation of the connectedness of the extreme equilibria /// These are generated only on demand - mutable List> m_cliques1, m_cliques2; + mutable Array> m_cliques1, m_cliques2; }; template From e095a82ec0a4b9df81b85a71a19824b190fa5472 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:02:16 +0000 Subject: [PATCH 03/11] Replace List with Array in enummixed --- src/core/util.h | 40 ++++++++++++++++++++++++++++++ src/solvers/enummixed/clique.h | 1 + src/solvers/enummixed/enummixed.cc | 18 ++++++-------- src/solvers/enummixed/enummixed.h | 2 +- src/tools/enummixed/enummixed.cc | 9 ++++--- 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/core/util.h b/src/core/util.h index f5678c706..a5c165e25 100644 --- a/src/core/util.h +++ b/src/core/util.h @@ -65,6 +65,46 @@ template bool contains(const std::map &map, const K return map.find(key) != map.end(); } +#include +#include +#include + +template class EnumerateView { +public: + explicit EnumerateView(C &p_range) : m_range(p_range) {} + + class iterator { + public: + using base_iterator = decltype(std::begin(std::declval())); + + iterator(std::size_t index, base_iterator it) : m_index(index), m_current(it) {} + + iterator &operator++() + { + ++m_index; + ++m_current; + return *this; + } + + bool operator!=(const iterator &p_other) const { return m_current != p_other.m_current; } + + auto operator*() const { return std::tie(m_index, *m_current); } + + private: + std::size_t m_index; + base_iterator m_current; + }; + + iterator begin() { return iterator{0, std::begin(m_range)}; } + + iterator end() { return iterator{0, std::end(m_range)}; } + +private: + C &m_range; +}; + +template auto enumerate(Range &p_range) { return EnumerateView(p_range); } + /// @brief A container adaptor which skips over a given value when iterating template class exclude_value { public: diff --git a/src/solvers/enummixed/clique.h b/src/solvers/enummixed/clique.h index 5de7a68f2..af7d9aa1c 100644 --- a/src/solvers/enummixed/clique.h +++ b/src/solvers/enummixed/clique.h @@ -203,6 +203,7 @@ class CliqueEnumerator { int node2; int nextedge; Edge() = default; + explicit Edge(const int n1, const int n2) : node1(n1), node2(n2) {} ~Edge() = default; bool operator==(const Edge &y) const { return (node1 == y.node1 && node2 == y.node2); } bool operator!=(const Edge &y) const { return !(*this == y); } diff --git a/src/solvers/enummixed/enummixed.cc b/src/solvers/enummixed/enummixed.cc index 85a0c9619..77cce0053 100644 --- a/src/solvers/enummixed/enummixed.cc +++ b/src/solvers/enummixed/enummixed.cc @@ -38,7 +38,7 @@ bool EqZero(const double &x) bool EqZero(const Rational &x) { return x == Rational(0); } template -List>> EnumMixedStrategySolution::GetCliques() const +Array>> EnumMixedStrategySolution::GetCliques() const { if (m_cliques1.empty()) { // Cliques are generated on demand @@ -48,19 +48,17 @@ List>> EnumMixedStrategySolution::GetCliques() c } Array edgelist(n); - for (size_t i = 1; i <= n; i++) { - edgelist[i].node1 = m_node1[i]; - edgelist[i].node2 = m_node2[i]; - } + std::transform(m_node1.begin(), m_node1.end(), m_node2.begin(), edgelist.begin(), + [](const int a, const int b) { return CliqueEnumerator::Edge(a, b); }); const CliqueEnumerator clique(edgelist, m_v2 + 1, m_v1 + 1); m_cliques1 = clique.GetCliques1(); m_cliques2 = clique.GetCliques2(); } - List>> solution; + Array>> solution; for (size_t cl = 1; cl <= m_cliques1.size(); cl++) { - solution.push_back(List>()); + solution.push_back(Array>()); for (size_t i = 1; i <= m_cliques1[cl].size(); i++) { for (size_t j = 1; j <= m_cliques2[cl].size(); j++) { MixedStrategyProfile profile(m_game->NewMixedStrategyProfile(static_cast(0))); @@ -138,10 +136,8 @@ EnumMixedStrategySolveDetailed(const Game &p_game, StrategyCallbackType p_onE Array vert1id(solution->m_v1); Array vert2id(solution->m_v2); - for (size_t i = 1; i <= vert1id.size(); vert1id[i++] = 0) - ; - for (size_t i = 1; i <= vert2id.size(); vert2id[i++] = 0) - ; + std::fill(vert1id.begin(), vert1id.end(), 0); + std::fill(vert2id.begin(), vert2id.end(), 0); int id1 = 0, id2 = 0; diff --git a/src/solvers/enummixed/enummixed.h b/src/solvers/enummixed/enummixed.h index c35700dfa..9c7a00141 100644 --- a/src/solvers/enummixed/enummixed.h +++ b/src/solvers/enummixed/enummixed.h @@ -44,7 +44,7 @@ template class EnumMixedStrategySolution { return m_extremeEquilibria; } - List>> GetCliques() const; + Array>> GetCliques() const; Game m_game; std::list> m_extremeEquilibria; diff --git a/src/tools/enummixed/enummixed.cc b/src/tools/enummixed/enummixed.cc index fbe035764..6f36fb8e5 100644 --- a/src/tools/enummixed/enummixed.cc +++ b/src/tools/enummixed/enummixed.cc @@ -32,12 +32,13 @@ using namespace Gambit; using namespace Gambit::Nash; template -void PrintCliques(const List>> &p_cliques, +void PrintCliques(const Array>> &p_cliques, std::shared_ptr> p_renderer) { - for (size_t cl = 1; cl <= p_cliques.size(); cl++) { - for (size_t i = 1; i <= p_cliques[cl].size(); i++) { - p_renderer->Render(p_cliques[cl][i], "convex-" + lexical_cast(cl)); + for (auto [cl, clique] : enumerate(p_cliques)) { + const std::string label = "convex-" + std::to_string(cl + 1); + for (const auto &profile : clique) { + p_renderer->Render(profile, label); } } } From c3cd380ec57137120380df9cbb7443c3a9a654c9 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:07:07 +0000 Subject: [PATCH 04/11] Replace List with Array in lcp --- src/solvers/lcp/efglcp.cc | 2 +- src/solvers/lcp/nfglcp.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/solvers/lcp/efglcp.cc b/src/solvers/lcp/efglcp.cc index 9b44b08e9..ee5e51f8a 100644 --- a/src/solvers/lcp/efglcp.cc +++ b/src/solvers/lcp/efglcp.cc @@ -57,7 +57,7 @@ template class NashLcpBehaviorSolver::Solution { Rational maxpay; std::map infosetOffset; T eps; - List> m_list; + Array> m_list; std::list> m_equilibria; explicit Solution(const Game &); diff --git a/src/solvers/lcp/nfglcp.cc b/src/solvers/lcp/nfglcp.cc index 37956e3c0..a5ae119e7 100644 --- a/src/solvers/lcp/nfglcp.cc +++ b/src/solvers/lcp/nfglcp.cc @@ -132,7 +132,7 @@ template class NashLcpStrategySolver { template class NashLcpStrategySolver::Solution { public: - List> m_bfsList; + Array> m_bfsList; std::list> m_equilibria; bool Contains(const Gambit::linalg::BFS &p_bfs) const { return contains(m_bfsList, p_bfs); } From 206440f4d885343999655b29fc9a97eb405e2e13 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:12:06 +0000 Subject: [PATCH 05/11] Replace List with Array in enumpoly --- src/solvers/enumpoly/behavextend.cc | 12 ++++++------ src/solvers/enumpoly/polysystem.h | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/solvers/enumpoly/behavextend.cc b/src/solvers/enumpoly/behavextend.cc index ccbcc1b4c..d1d31c470 100644 --- a/src/solvers/enumpoly/behavextend.cc +++ b/src/solvers/enumpoly/behavextend.cc @@ -47,7 +47,7 @@ std::list TerminalNodes(const Game &p_efg) return ret; } -void DeviationInfosets(List &answer, const BehaviorSupportProfile &big_supp, +void DeviationInfosets(Array &answer, const BehaviorSupportProfile &big_supp, const GamePlayer &p_player, const GameNode &p_node, const GameAction &p_action) { @@ -73,11 +73,11 @@ void DeviationInfosets(List &answer, const BehaviorSupportProfile & } } -List DeviationInfosets(const BehaviorSupportProfile &big_supp, - const GamePlayer &p_player, const GameInfoset &p_infoset, - const GameAction &p_action) +Array DeviationInfosets(const BehaviorSupportProfile &big_supp, + const GamePlayer &p_player, const GameInfoset &p_infoset, + const GameAction &p_action) { - List answer; + Array answer; for (auto member : p_infoset->GetMembers()) { DeviationInfosets(answer, big_supp, p_player, member, p_action); } @@ -107,7 +107,7 @@ PolynomialSystem ActionProbsSumToOneIneqs(const MixedBehaviorProfile DeviationSupports(const BehaviorSupportProfile &big_supp, - const List &isetlist) + const Array &isetlist) { std::list answer; diff --git a/src/solvers/enumpoly/polysystem.h b/src/solvers/enumpoly/polysystem.h index 919b1fafc..f96990156 100644 --- a/src/solvers/enumpoly/polysystem.h +++ b/src/solvers/enumpoly/polysystem.h @@ -28,13 +28,12 @@ namespace Gambit { template class PolynomialSystem { -private: std::shared_ptr m_space; std::list> m_system; public: - using iterator = typename List>::iterator; - using const_iterator = typename List>::const_iterator; + using iterator = typename std::list>::iterator; + using const_iterator = typename std::list>::const_iterator; PolynomialSystem(std::shared_ptr p_space) : m_space(p_space) {} PolynomialSystem(const PolynomialSystem &) = default; From 2e8f0cd3b1d5bff75a3c2422c84013555d3cdb63 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:15:48 +0000 Subject: [PATCH 06/11] Replace List with Array in gametracer --- src/tools/gt/nfggnm.cc | 10 +++++----- src/tools/gt/nfggt.cc | 10 +++++----- src/tools/gt/nfgipa.cc | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tools/gt/nfggnm.cc b/src/tools/gt/nfggnm.cc index 4f1eb3623..e824c5c10 100644 --- a/src/tools/gt/nfggnm.cc +++ b/src/tools/gt/nfggnm.cc @@ -31,10 +31,10 @@ using namespace Gambit; using namespace Gambit::Nash; -extern List> ReadStrategyPerturbations(const Game &p_game, - std::istream &p_stream); -extern List> RandomStrategyPerturbations(const Game &p_game, - int p_count); +extern Array> ReadStrategyPerturbations(const Game &p_game, + std::istream &p_stream); +extern Array> RandomStrategyPerturbations(const Game &p_game, + int p_count); void PrintBanner(std::ostream &p_stream) { @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) try { const Game game = ReadGame(*input_stream); auto renderer = MakeMixedStrategyProfileRenderer(std::cout, numDecimals, false); - List> perts; + Array> perts; if (!startFile.empty()) { std::ifstream startPerts(startFile.c_str()); perts = ReadStrategyPerturbations(game, startPerts); diff --git a/src/tools/gt/nfggt.cc b/src/tools/gt/nfggt.cc index 03cac880d..f44bb4eae 100644 --- a/src/tools/gt/nfggt.cc +++ b/src/tools/gt/nfggt.cc @@ -24,10 +24,10 @@ using namespace Gambit; -List> ReadStrategyPerturbations(const Game &p_game, - std::istream &p_stream) +Array> ReadStrategyPerturbations(const Game &p_game, + std::istream &p_stream) { - List> profiles; + Array> profiles; while (!p_stream.eof() && !p_stream.bad()) { MixedStrategyProfile p(p_game->NewMixedStrategyProfile(0.0)); for (size_t i = 1; i <= p.MixedProfileLength(); i++) { @@ -48,10 +48,10 @@ List> ReadStrategyPerturbations(const Game &p_game, return profiles; } -List> RandomStrategyPerturbations(const Game &p_game, int p_count) +Array> RandomStrategyPerturbations(const Game &p_game, int p_count) { std::default_random_engine engine; - List> profiles; + Array> profiles; for (int i = 1; i <= p_count; i++) { profiles.push_back(p_game->NewRandomStrategyProfile(engine)); } diff --git a/src/tools/gt/nfgipa.cc b/src/tools/gt/nfgipa.cc index 18954dedf..91a14761b 100644 --- a/src/tools/gt/nfgipa.cc +++ b/src/tools/gt/nfgipa.cc @@ -31,10 +31,10 @@ using namespace Gambit; using namespace Gambit::Nash; using namespace Gambit::gametracer; -extern List> ReadStrategyPerturbations(const Game &p_game, - std::istream &p_stream); -extern List> RandomStrategyPerturbations(const Game &p_game, - int p_count); +extern Array> ReadStrategyPerturbations(const Game &p_game, + std::istream &p_stream); +extern Array> RandomStrategyPerturbations(const Game &p_game, + int p_count); void PrintBanner(std::ostream &p_stream) { @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) const Game game = ReadGame(*input_stream); auto renderer = MakeMixedStrategyProfileRenderer(std::cout, numDecimals, false); - List> perts; + Array> perts; if (!startFile.empty()) { std::ifstream startPerts(startFile.c_str()); perts = ReadStrategyPerturbations(game, startPerts); From be6742dca060cb137e75d23e95577ae4b05ad5d8 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:18:50 +0000 Subject: [PATCH 07/11] Replace List with Array in tools --- src/tools/liap/liap.cc | 22 ++++++++++++---------- src/tools/simpdiv/nfgsimpdiv.cc | 12 ++++++------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/tools/liap/liap.cc b/src/tools/liap/liap.cc index ca4e0c186..121007ddf 100644 --- a/src/tools/liap/liap.cc +++ b/src/tools/liap/liap.cc @@ -59,9 +59,10 @@ void PrintHelp(char *progname) exit(1); } -List> ReadStrategyProfiles(const Game &p_game, std::istream &p_stream) +Array> ReadStrategyProfiles(const Game &p_game, + std::istream &p_stream) { - List> profiles; + Array> profiles; while (!p_stream.eof() && !p_stream.bad()) { MixedStrategyProfile p(p_game->NewMixedStrategyProfile(0.0)); for (size_t i = 1; i <= p.MixedProfileLength(); i++) { @@ -82,19 +83,20 @@ List> ReadStrategyProfiles(const Game &p_game, std: return profiles; } -List> RandomStrategyProfiles(const Game &p_game, int p_count) +Array> RandomStrategyProfiles(const Game &p_game, int p_count) { std::default_random_engine engine; - List> profiles; + Array> profiles; for (int i = 1; i <= p_count; i++) { profiles.push_back(p_game->NewRandomStrategyProfile(engine)); } return profiles; } -List> ReadBehaviorProfiles(const Game &p_game, std::istream &p_stream) +Array> ReadBehaviorProfiles(const Game &p_game, + std::istream &p_stream) { - List> profiles; + Array> profiles; while (!p_stream.eof() && !p_stream.bad()) { MixedBehaviorProfile p(p_game); for (size_t i = 1; i <= p.BehaviorProfileLength(); i++) { @@ -115,10 +117,10 @@ List> ReadBehaviorProfiles(const Game &p_game, std: return profiles; } -List> RandomBehaviorProfiles(const Game &p_game, int p_count) +Array> RandomBehaviorProfiles(const Game &p_game, int p_count) { std::default_random_engine engine; - List> profiles; + Array> profiles; for (int i = 1; i <= p_count; i++) { profiles.push_back(p_game->NewRandomBehaviorProfile(engine)); } @@ -203,7 +205,7 @@ int main(int argc, char *argv[]) try { const Game game = ReadGame(*input_stream); if (!game->IsTree() || useStrategic) { - List> starts; + Array> starts; if (!startFile.empty()) { std::ifstream startPoints(startFile.c_str()); starts = ReadStrategyProfiles(game, startPoints); @@ -225,7 +227,7 @@ int main(int argc, char *argv[]) } } else { - List> starts; + Array> starts; if (!startFile.empty()) { std::ifstream startPoints(startFile.c_str()); starts = ReadBehaviorProfiles(game, startPoints); diff --git a/src/tools/simpdiv/nfgsimpdiv.cc b/src/tools/simpdiv/nfgsimpdiv.cc index 3105486f8..eaa2ed777 100644 --- a/src/tools/simpdiv/nfgsimpdiv.cc +++ b/src/tools/simpdiv/nfgsimpdiv.cc @@ -30,9 +30,9 @@ using namespace Gambit; using namespace Gambit::Nash; -List> ReadProfiles(const Game &p_game, std::istream &p_stream) +Array> ReadProfiles(const Game &p_game, std::istream &p_stream) { - List> profiles; + Array> profiles; while (!p_stream.eof() && !p_stream.bad()) { MixedStrategyProfile p(p_game->NewMixedStrategyProfile(Rational(0))); for (size_t i = 1; i <= p.MixedProfileLength(); i++) { @@ -53,11 +53,11 @@ List> ReadProfiles(const Game &p_game, std::istre return profiles; } -List> RandomProfiles(const Game &p_game, int p_count, - const Rational &denom) +Array> RandomProfiles(const Game &p_game, int p_count, + const Rational &denom) { std::default_random_engine engine; - List> profiles; + Array> profiles; for (int i = 1; i <= p_count; i++) { std::cout << "profile " << i << std::endl; profiles.push_back(p_game->NewRandomStrategyProfile(denom, engine)); @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) try { const Game game = ReadGame(*input_stream); - List> starts; + Array> starts; if (!startFile.empty()) { std::ifstream startPoints(startFile.c_str()); starts = ReadProfiles(game, startPoints); From 3d566b0ef5553895b12ba82f5c3cd17c3386cb68 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:23:37 +0000 Subject: [PATCH 08/11] Final removal of List class. --- Makefile.am | 1 - src/core/core.h | 1 - src/core/list.h | 144 ---------------------------------------- src/pygambit/gambit.pxd | 18 ++--- 4 files changed, 6 insertions(+), 158 deletions(-) delete mode 100644 src/core/list.h diff --git a/Makefile.am b/Makefile.am index a1514ea45..f5178efe5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -246,7 +246,6 @@ core_SOURCES = \ src/core/core.h \ src/core/util.h \ src/core/array.h \ - src/core/list.h \ src/core/vector.h \ src/core/recarray.h \ src/core/matrix.h \ diff --git a/src/core/core.h b/src/core/core.h index 726235445..d865fefb8 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -25,7 +25,6 @@ #include "util.h" #include "array.h" -#include "list.h" #include "recarray.h" #include "vector.h" #include "matrix.h" diff --git a/src/core/list.h b/src/core/list.h deleted file mode 100644 index 52dc341b1..000000000 --- a/src/core/list.h +++ /dev/null @@ -1,144 +0,0 @@ -// -// This file is part of Gambit -// Copyright (c) 1994-2025, The Gambit Project (https://www.gambit-project.org) -// -// FILE: src/core/list.h -// A generic linked-list container class -// -// 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 2 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, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// - -#ifndef GAMBIT_CORE_LIST_H -#define GAMBIT_CORE_LIST_H - -#include - -namespace Gambit { - -/// @brief A linked-list container -/// -/// This is a lightweight wrapper around std::list. It exists as a transitional -/// class between Gambit's legacy linked-list implementation Gambit::List and -/// STL's list. -/// -/// Gambit's List container supported the index operator [], which is not defined -/// on STL lists. Therefore this class provides such an operator by wrapping -/// an appropriate iterator-based operation. This is very inefficient! However, -/// the [] operator and indexing is tightly embedded in the remaining uses of this -/// class, so this operator provides a refactoring path while the remaining uses -/// are rewritten. -/// -/// Note importantly that the index operator [] is **1-based** - that is, the first -/// element of the list is 1, not 0. -template class List { - std::list m_list; - -public: - using iterator = typename std::list::iterator; - using const_iterator = typename std::list::const_iterator; - using value_type = typename std::list::value_type; - using size_type = typename std::list::size_type; - - List() = default; - List(const List &) = default; - List(List &&) noexcept = default; - List &operator=(List &&) noexcept = default; - ~List() = default; - - List &operator=(const List &) = default; - - const T &operator[](size_type p_index) const - { - if (p_index < 1 || p_index > m_list.size()) { - throw std::out_of_range("Index out of range in List"); - } - return *std::next(m_list.cbegin(), p_index - 1); - } - - T &operator[](size_type p_index) - { - if (p_index < 1 || p_index > m_list.size()) { - throw std::out_of_range("Index out of range in List"); - } - return *std::next(m_list.begin(), p_index - 1); - } - - /// @name STL-style interface - /// - /// These operations forward STL-type operations to the underlying list. - /// This does not provide all operations on std::list, only ones used in - /// existing code. Rather than adding new functions here, existing code - /// should be rewritten to use std::list directly. - ///@{ - /// Return whether the list container is empty (has size 0). - bool empty() const { return m_list.empty(); } - /// Return the number of elements in the list container. - size_type size() const { return m_list.size(); } - /// Adds a new element at the beginning of the list container - void push_front(const T &val) { m_list.push_front(val); } - /// Adds a new element at the end of the list container, after its - /// current last element. - void push_back(const T &val) { m_list.push_back(val); } - /// Removes the last element - void pop_back() { m_list.pop_back(); } - /// Inserts the value at the specified position - void insert(iterator pos, const T &value) { m_list.insert(pos, value); } - /// Erases the element at the specified position - iterator erase(iterator pos) { return m_list.erase(pos); } - template void remove_if(Predicate pred) - { - for (auto it = begin(); it != end();) { - if (pred(*it)) { - it = erase(it); - } - else { - ++it; - } - } - } - - /// Removes all elements from the list container (which are destroyed), - /// leaving the container with a size of 0. - void clear() { m_list.clear(); } - /// Returns a reference to the first element in the list container. - T &front() { return m_list.front(); } - /// Returns a reference to the first element in the list container. - const T &front() const { return m_list.front(); } - /// Returns a reference to the last element in the list container. - T &back() { return m_list.back(); } - /// Returns a reference to the last element in the list container. - const T &back() const { return m_list.back(); } - - bool operator==(const List &b) const { return m_list == b.m_list; } - bool operator!=(const List &b) const { return m_list != b.m_list; } - - /// Return a forward iterator starting at the beginning of the list - iterator begin() { return m_list.begin(); } - /// Return a forward iterator past the end of the list - iterator end() { return m_list.end(); } - /// Return a const forward iterator starting at the beginning of the list - const_iterator begin() const { return m_list.begin(); } - /// Return a const forward iterator past the end of the list - const_iterator end() const { return m_list.end(); } - /// Return a const forward iterator starting at the beginning of the list - const_iterator cbegin() const { return m_list.cbegin(); } - /// Return a const forward iterator past the end of the list - const_iterator cend() const { return m_list.cend(); } - ///@} -}; - -} // namespace Gambit - -#endif // GAMBIT_CORE_LIST_H diff --git a/src/pygambit/gambit.pxd b/src/pygambit/gambit.pxd index 335705471..7c310a0ad 100644 --- a/src/pygambit/gambit.pxd +++ b/src/pygambit/gambit.pxd @@ -42,12 +42,6 @@ cdef extern from "core/array.h": iterator end() except + -cdef extern from "core/list.h": - cdef cppclass c_List "List"[T]: - T & getitem "operator[]"(int) except + - int size() except + - void push_back(T) except + - cdef extern from "games/game.h": cdef cppclass c_GameRep "GameRep" cdef cppclass c_GameStrategyRep "GameStrategyRep" @@ -463,22 +457,22 @@ cdef extern from "util.h": c_GameAction, c_Rational) except + shared_ptr[c_MixedStrategyProfile[double]] copyitem_list_mspd "sharedcopyitem"( - c_List[c_MixedStrategyProfile[double]], int + stdlist[c_MixedStrategyProfile[double]], int ) except + shared_ptr[c_MixedStrategyProfile[c_Rational]] copyitem_list_mspr "sharedcopyitem"( - c_List[c_MixedStrategyProfile[c_Rational]], int + stdlist[c_MixedStrategyProfile[c_Rational]], int ) except + shared_ptr[c_MixedBehaviorProfile[double]] copyitem_list_mbpd "sharedcopyitem"( - c_List[c_MixedBehaviorProfile[double]], int + stdlist[c_MixedBehaviorProfile[double]], int ) except + shared_ptr[c_MixedBehaviorProfile[c_Rational]] copyitem_list_mbpr "sharedcopyitem"( - c_List[c_MixedBehaviorProfile[c_Rational]], int + stdlist[c_MixedBehaviorProfile[c_Rational]], int ) except + shared_ptr[c_LogitQREMixedStrategyProfile] copyitem_list_qrem "sharedcopyitem"( - c_List[c_LogitQREMixedStrategyProfile], int + stdlist[c_LogitQREMixedStrategyProfile], int ) except + shared_ptr[c_LogitQREMixedBehaviorProfile] copyitem_list_qreb "sharedcopyitem"( - c_List[c_LogitQREMixedBehaviorProfile], int + stdlist[c_LogitQREMixedBehaviorProfile], int ) except + From 51087ba0a495b6b732c1c2dac3921a3df846a394 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 10:32:14 +0000 Subject: [PATCH 09/11] Fix misplaced header includes --- src/core/util.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/util.h b/src/core/util.h index a5c165e25..93d570d5e 100644 --- a/src/core/util.h +++ b/src/core/util.h @@ -65,10 +65,6 @@ template bool contains(const std::map &map, const K return map.find(key) != map.end(); } -#include -#include -#include - template class EnumerateView { public: explicit EnumerateView(C &p_range) : m_range(p_range) {} @@ -77,7 +73,10 @@ template class EnumerateView { public: using base_iterator = decltype(std::begin(std::declval())); - iterator(std::size_t index, base_iterator it) : m_index(index), m_current(it) {} + iterator(const std::size_t p_index, base_iterator p_current) + : m_index(p_index), m_current(p_current) + { + } iterator &operator++() { @@ -87,7 +86,6 @@ template class EnumerateView { } bool operator!=(const iterator &p_other) const { return m_current != p_other.m_current; } - auto operator*() const { return std::tie(m_index, *m_current); } private: @@ -96,14 +94,13 @@ template class EnumerateView { }; iterator begin() { return iterator{0, std::begin(m_range)}; } - iterator end() { return iterator{0, std::end(m_range)}; } private: C &m_range; }; -template auto enumerate(Range &p_range) { return EnumerateView(p_range); } +template auto enumerate(C &p_range) { return EnumerateView(p_range); } /// @brief A container adaptor which skips over a given value when iterating template class exclude_value { From 95323518943dda4743e303aebb49f38e11b4ef42 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 11:04:36 +0000 Subject: [PATCH 10/11] Fit initialisation in edge --- src/solvers/enummixed/clique.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/solvers/enummixed/clique.h b/src/solvers/enummixed/clique.h index af7d9aa1c..9d08e5fc9 100644 --- a/src/solvers/enummixed/clique.h +++ b/src/solvers/enummixed/clique.h @@ -199,9 +199,8 @@ class CliqueEnumerator { public: class Edge { public: - int node1; - int node2; - int nextedge; + int node1, node2, nextedge{}; + Edge() = default; explicit Edge(const int n1, const int n2) : node1(n1), node2(n2) {} ~Edge() = default; From eb959203383c83d36363a6fbd9913cab02ad9af1 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Mon, 15 Dec 2025 16:40:13 +0000 Subject: [PATCH 11/11] Fix edgelist construction --- src/solvers/enummixed/clique.h | 1 - src/solvers/enummixed/enummixed.cc | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/solvers/enummixed/clique.h b/src/solvers/enummixed/clique.h index 9d08e5fc9..7a7efee6c 100644 --- a/src/solvers/enummixed/clique.h +++ b/src/solvers/enummixed/clique.h @@ -201,7 +201,6 @@ class CliqueEnumerator { public: int node1, node2, nextedge{}; - Edge() = default; explicit Edge(const int n1, const int n2) : node1(n1), node2(n2) {} ~Edge() = default; bool operator==(const Edge &y) const { return (node1 == y.node1 && node2 == y.node2); } diff --git a/src/solvers/enummixed/enummixed.cc b/src/solvers/enummixed/enummixed.cc index 77cce0053..c20e09e4b 100644 --- a/src/solvers/enummixed/enummixed.cc +++ b/src/solvers/enummixed/enummixed.cc @@ -47,8 +47,9 @@ Array>> EnumMixedStrategySolution::GetCliques() throw DimensionException(); } - Array edgelist(n); - std::transform(m_node1.begin(), m_node1.end(), m_node2.begin(), edgelist.begin(), + Array edgelist; + edgelist.reserve(n); + std::transform(m_node1.begin(), m_node1.end(), m_node2.begin(), std::back_inserter(edgelist), [](const int a, const int b) { return CliqueEnumerator::Edge(a, b); }); const CliqueEnumerator clique(edgelist, m_v2 + 1, m_v1 + 1);