Skip to content

Commit e182a85

Browse files
committed
Replace bespoke Game reference-counting with std::shared_ptr.
This removes the legacy reference-counting system for tracking references to games with one based on std::shared_ptr.
1 parent 89cbddc commit e182a85

10 files changed

Lines changed: 63 additions & 101 deletions

File tree

src/games/behavmixed.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ MixedBehaviorProfile<T>::MixedBehaviorProfile(const MixedStrategyProfile<T> &p_p
142142
GameNodeRep *root = m_support.GetGame()->GetRoot();
143143

144144
const StrategySupportProfile &support = p_profile.GetSupport();
145-
GameRep *game = m_support.GetGame();
145+
GameRep *game = m_support.GetGame().get();
146146

147147
for (auto player : game->GetPlayers()) {
148148
std::map<GameNode, T> map_nvals, map_bvals;

src/games/game.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class GameNodeRep;
5454
using GameNode = GameObjectPtr<GameNodeRep>;
5555

5656
class GameRep;
57-
using Game = GameObjectPtr<GameRep>;
57+
using Game = std::shared_ptr<GameRep>;
5858

5959
template <class P, class T> class ElementCollection {
6060
P m_owner{nullptr};
@@ -488,7 +488,7 @@ class GameNodeRep : public GameObject {
488488
};
489489

490490
/// This is the class for representing an arbitrary finite game.
491-
class GameRep : public BaseGameRep {
491+
class GameRep : public std::enable_shared_from_this<GameRep> {
492492
friend class GameOutcomeRep;
493493
friend class GameNodeRep;
494494
friend class PureStrategyProfileRep;
@@ -536,7 +536,8 @@ class GameRep : public BaseGameRep {
536536

537537
iterator() = default;
538538

539-
iterator(const Game &game, const GameNode &start_node) : m_owner(game), m_current_node(start_node)
539+
iterator(const Game &game, const GameNode &start_node)
540+
: m_owner(game), m_current_node(start_node)
540541
{
541542
if (!start_node) {
542543
return;
@@ -600,7 +601,7 @@ class GameRep : public BaseGameRep {
600601
/// @name Lifecycle
601602
//@{
602603
/// Clean up the game
603-
~GameRep() override;
604+
virtual ~GameRep();
604605

605606
/// Create a copy of the game, as a new game
606607
virtual Game Copy() const = 0;
@@ -778,7 +779,10 @@ class GameRep : public BaseGameRep {
778779
/// Returns the pl'th player in the game
779780
GamePlayer GetPlayer(int pl) const { return m_players.at(pl - 1); }
780781
/// Returns the set of players in the game
781-
Players GetPlayers() const { return Players(this, &m_players); }
782+
Players GetPlayers() const
783+
{
784+
return Players(std::const_pointer_cast<GameRep>(shared_from_this()), &m_players);
785+
}
782786
/// Returns the chance (nature) player
783787
virtual GamePlayer GetChance() const = 0;
784788
/// Creates a new player in the game, with no moves
@@ -798,7 +802,10 @@ class GameRep : public BaseGameRep {
798802
/// Returns the index'th outcome defined in the game
799803
GameOutcome GetOutcome(int index) const { return m_outcomes.at(index - 1); }
800804
/// Returns the set of outcomes in the game
801-
Outcomes GetOutcomes() const { return Outcomes(this, &m_outcomes); }
805+
Outcomes GetOutcomes() const
806+
{
807+
return Outcomes(std::const_pointer_cast<GameRep>(shared_from_this()), &m_outcomes);
808+
}
802809
/// Creates a new outcome in the game
803810
virtual GameOutcome NewOutcome() { throw UndefinedException(); }
804811
/// Deletes the specified outcome from the game
@@ -810,7 +817,7 @@ class GameRep : public BaseGameRep {
810817
/// Returns the root node of the game
811818
virtual GameNode GetRoot() const = 0;
812819
/// Returns a range that can be used to iterate over the nodes of the game
813-
Nodes GetNodes() const { return Nodes(this); }
820+
Nodes GetNodes() const { return Nodes(std::const_pointer_cast<GameRep>(shared_from_this())); }
814821
/// Returns the number of nodes in the game
815822
virtual size_t NumNodes() const = 0;
816823
/// Returns the number of non-terminal nodes in the game
@@ -834,7 +841,7 @@ class GameRep : public BaseGameRep {
834841
// These must be postponed to here in the file because they require
835842
// all classes to be defined.
836843

837-
inline Game GameOutcomeRep::GetGame() const { return m_game; }
844+
inline Game GameOutcomeRep::GetGame() const { return m_game->shared_from_this(); }
838845

839846
template <class T> const T &GameOutcomeRep::GetPayoff(const GamePlayer &p_player) const
840847
{
@@ -867,11 +874,11 @@ inline void GameOutcomeRep::SetPayoff(const GamePlayer &p_player, const Number &
867874

868875
inline GamePlayer GameStrategyRep::GetPlayer() const { return m_player; }
869876

870-
inline Game GameInfosetRep::GetGame() const { return m_game; }
877+
inline Game GameInfosetRep::GetGame() const { return m_game->shared_from_this(); }
871878
inline GamePlayer GameInfosetRep::GetPlayer() const { return m_player; }
872879
inline bool GameInfosetRep::IsChanceInfoset() const { return m_player->IsChance(); }
873880

874-
inline Game GamePlayerRep::GetGame() const { return m_game; }
881+
inline Game GamePlayerRep::GetGame() const { return m_game->shared_from_this(); }
875882
inline GameStrategy GamePlayerRep::GetStrategy(int st) const
876883
{
877884
m_game->BuildComputedValues();
@@ -883,7 +890,7 @@ inline GamePlayerRep::Strategies GamePlayerRep::GetStrategies() const
883890
return Strategies(this, &m_strategies);
884891
}
885892

886-
inline Game GameNodeRep::GetGame() const { return m_game; }
893+
inline Game GameNodeRep::GetGame() const { return m_game->shared_from_this(); }
887894

888895
//=======================================================================
889896

src/games/gameagg.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,20 @@ GameStrategy GameAGGRep::GetStrategy(int p_index) const
226226

227227
PureStrategyProfile GameAGGRep::NewPureStrategyProfile() const
228228
{
229-
return PureStrategyProfile(
230-
std::make_shared<AGGPureStrategyProfileRep>(const_cast<GameAGGRep *>(this)));
229+
return PureStrategyProfile(std::make_shared<AGGPureStrategyProfileRep>(
230+
std::const_pointer_cast<GameRep>(shared_from_this())));
231231
}
232232

233233
MixedStrategyProfile<double> GameAGGRep::NewMixedStrategyProfile(double) const
234234
{
235235
return MixedStrategyProfile<double>(new AGGMixedStrategyProfileRep<double>(
236-
StrategySupportProfile(const_cast<GameAGGRep *>(this))));
236+
StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))));
237237
}
238238

239239
MixedStrategyProfile<Rational> GameAGGRep::NewMixedStrategyProfile(const Rational &) const
240240
{
241241
return MixedStrategyProfile<Rational>(new AGGMixedStrategyProfileRep<Rational>(
242-
StrategySupportProfile(const_cast<GameAGGRep *>(this))));
242+
StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))));
243243
}
244244
MixedStrategyProfile<double>
245245
GameAGGRep::NewMixedStrategyProfile(double, const StrategySupportProfile &spt) const
@@ -265,7 +265,7 @@ bool GameAGGRep::IsConstSum() const
265265
sum += profile->GetPayoff(player);
266266
}
267267

268-
for (auto iter : StrategyContingencies(Game(this))) {
268+
for (auto iter : StrategyContingencies(std::const_pointer_cast<GameRep>(shared_from_this()))) {
269269
Rational newsum(0);
270270
for (const auto &player : m_players) {
271271
newsum += iter->GetPayoff(player);

src/games/gameagg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class GameAGGRep : public GameRep {
120120
inline Game ReadAggFile(std::istream &p_stream)
121121
{
122122
try {
123-
return new GameAGGRep(agg::AGG::makeAGG(p_stream));
123+
return std::make_shared<GameAGGRep>(agg::AGG::makeAGG(p_stream));
124124
}
125125
catch (std::runtime_error &ex) {
126126
throw InvalidFileException(ex.what());

src/games/gamebagg.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,20 +244,20 @@ Array<int> GameBAGGRep::NumStrategies() const
244244

245245
PureStrategyProfile GameBAGGRep::NewPureStrategyProfile() const
246246
{
247-
return PureStrategyProfile(
248-
std::make_shared<BAGGPureStrategyProfileRep>(const_cast<GameBAGGRep *>(this)));
247+
return PureStrategyProfile(std::make_shared<BAGGPureStrategyProfileRep>(
248+
std::const_pointer_cast<GameRep>(shared_from_this())));
249249
}
250250

251251
MixedStrategyProfile<double> GameBAGGRep::NewMixedStrategyProfile(double) const
252252
{
253253
return MixedStrategyProfile<double>(new BAGGMixedStrategyProfileRep<double>(
254-
StrategySupportProfile(const_cast<GameBAGGRep *>(this))));
254+
StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))));
255255
}
256256

257257
MixedStrategyProfile<Rational> GameBAGGRep::NewMixedStrategyProfile(const Rational &) const
258258
{
259259
return MixedStrategyProfile<Rational>(new BAGGMixedStrategyProfileRep<Rational>(
260-
StrategySupportProfile(const_cast<GameBAGGRep *>(this))));
260+
StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))));
261261
}
262262
MixedStrategyProfile<double>
263263
GameBAGGRep::NewMixedStrategyProfile(double, const StrategySupportProfile &spt) const

src/games/gamebagg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class GameBAGGRep : public GameRep {
128128
inline Game ReadBaggFile(std::istream &in)
129129
{
130130
try {
131-
return new GameBAGGRep(agg::BAGG::makeBAGG(in));
131+
return std::make_shared<GameBAGGRep>(agg::BAGG::makeBAGG(in));
132132
}
133133
catch (std::runtime_error &ex) {
134134
throw InvalidFileException(ex.what());

src/games/gameobject.h

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -84,52 +84,6 @@ class GameObject {
8484
//@}
8585
};
8686

87-
class BaseGameRep {
88-
protected:
89-
int m_refCount{0};
90-
91-
public:
92-
/// @name Lifecycle
93-
//@{
94-
/// Constructor
95-
BaseGameRep() = default;
96-
97-
/// Destructor
98-
virtual ~BaseGameRep() = default;
99-
//@}
100-
101-
/// @name Validation
102-
//@{
103-
/// Is the object still valid?
104-
bool IsValid() const { return true; }
105-
106-
/// Invalidate the object; delete if not referenced elsewhere
107-
void Invalidate()
108-
{
109-
if (!m_refCount) {
110-
delete this;
111-
}
112-
}
113-
//@}
114-
115-
/// @name Reference counting
116-
//@{
117-
/// Increment the reference count
118-
void IncRef() { m_refCount++; }
119-
120-
/// Decrement the reference count; delete if reference count is zero.
121-
void DecRef()
122-
{
123-
if (!--m_refCount) {
124-
delete this;
125-
}
126-
}
127-
128-
/// Returns the reference count
129-
int RefCount() const { return m_refCount; }
130-
//@}
131-
};
132-
13387
/// An exception thrown when attempting to dereference an invalidated object
13488
class InvalidObjectException : public Exception {
13589
public:

src/games/gametable.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ std::shared_ptr<PureStrategyProfileRep> TablePureStrategyProfileRep::Copy() cons
6666

6767
Game NewTable(const std::vector<int> &p_dim, bool p_sparseOutcomes /*= false*/)
6868
{
69-
return new GameTableRep(p_dim, p_sparseOutcomes);
69+
return std::make_shared<GameTableRep>(p_dim, p_sparseOutcomes);
7070
}
7171

7272
//------------------------------------------------------------------------
@@ -116,8 +116,8 @@ Rational TablePureStrategyProfileRep::GetStrategyValue(const GameStrategy &p_str
116116

117117
PureStrategyProfile GameTableRep::NewPureStrategyProfile() const
118118
{
119-
return PureStrategyProfile(
120-
std::make_shared<TablePureStrategyProfileRep>(const_cast<GameTableRep *>(this)));
119+
return PureStrategyProfile(std::make_shared<TablePureStrategyProfileRep>(
120+
std::const_pointer_cast<GameRep>(shared_from_this())));
121121
}
122122

123123
//========================================================================
@@ -308,7 +308,7 @@ bool GameTableRep::IsConstSum() const
308308
sum += profile->GetPayoff(player);
309309
}
310310

311-
for (auto iter : StrategyContingencies(Game(this))) {
311+
for (auto iter : StrategyContingencies(std::const_pointer_cast<GameRep>(shared_from_this()))) {
312312
Rational newsum(0);
313313
for (const auto &player : m_players) {
314314
newsum += iter->GetPayoff(player);
@@ -401,7 +401,7 @@ void GameTableRep::DeleteOutcome(const GameOutcome &p_outcome)
401401

402402
GameStrategy GameTableRep::NewStrategy(const GamePlayer &p_player, const std::string &p_label)
403403
{
404-
if (p_player->GetGame() != this) {
404+
if (p_player->GetGame().get() != this) {
405405
throw MismatchException();
406406
}
407407
IncrementVersion();
@@ -437,13 +437,13 @@ void GameTableRep::DeleteStrategy(const GameStrategy &p_strategy)
437437

438438
MixedStrategyProfile<double> GameTableRep::NewMixedStrategyProfile(double) const
439439
{
440-
return StrategySupportProfile(const_cast<GameTableRep *>(this))
440+
return StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))
441441
.NewMixedStrategyProfile<double>();
442442
}
443443

444444
MixedStrategyProfile<Rational> GameTableRep::NewMixedStrategyProfile(const Rational &) const
445445
{
446-
return StrategySupportProfile(const_cast<GameTableRep *>(this))
446+
return StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this()))
447447
.NewMixedStrategyProfile<Rational>();
448448
}
449449

@@ -477,8 +477,8 @@ void GameTableRep::RebuildTable()
477477
std::vector<GameOutcomeRep *> newResults(size);
478478
std::fill(newResults.begin(), newResults.end(), nullptr);
479479

480-
for (auto iter :
481-
StrategyContingencies(StrategySupportProfile(const_cast<GameTableRep *>(this)))) {
480+
for (auto iter : StrategyContingencies(
481+
StrategySupportProfile(std::const_pointer_cast<GameRep>(shared_from_this())))) {
482482
long newindex = 0L;
483483
for (const auto &player : m_players) {
484484
if (iter->GetStrategy(player)->m_offset < 0) {

0 commit comments

Comments
 (0)