Skip to content

Commit 49aaee3

Browse files
committed
Merge branch 'master' into dev_delist
# Conflicts: # src/core/util.h
2 parents eb95920 + 580fb0d commit 49aaee3

30 files changed

Lines changed: 804 additions & 841 deletions

.github/pull_request_template.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
_Thanks for contributing to Gambit! Before you submitting or reviewing a pull request, check out our [guidelines for contributing](https://gambitproject.readthedocs.io/en/latest/developer.contributing.html)._
2+
3+
_The person submitting the PR should ensure it has an informative title and update the headers below, before marking the PR as ready for review and assigning reviewers._
4+
5+
### Issues closed by this PR
6+
7+
_Add any issues that are being closed by this PR to the list. Use "Closes" or [another keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) followed by the issue number._
8+
9+
- Closes #ISSUE_NUMBER
10+
11+
### Description of the changes in this PR
12+
13+
_Update the description of the changes made in this PR. You can delete this section if the changes are already fully described in the linked issues._
14+
15+
This PR ...
16+
17+
### How to review this PR
18+
19+
_The gambit repository contains source code and documentation for several different components. Explain how a reviewer should approach reviewing the specific changes made in this PR._
20+
21+
_For example, you might include instructions like:_
22+
- _"Review code changes and ensure tests cover edge cases"_
23+
- _"Rebuild the GUI from this branch, then test features X, Y, Z work as expected"_
24+
- _"Click the link to the documentation page and sense check by reading"_

doc/developer.contributing.rst

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ version.
3737

3838
1. To get started contributing code in the `Gambit GitHub repo <https://github.com/gambitproject/gambit>`__, do one of the following:
3939

40-
- Core developers: request contributor access from one of the `team <https://www.gambit-project.org/team/>`__
41-
- External contributors: fork the repository on GitHub.
40+
- Core developers: request contributor access from one of the `team <https://www.gambit-project.org/team/>`__
41+
- External contributors: fork the repository on GitHub.
4242

4343
2. Clone the repository to your local machine ::
4444

@@ -63,9 +63,9 @@ version.
6363

6464
Having `pre-commit` installed is recommended as it runs many of the same checks that are automatically conducted on any pull request. Every time you commit, it will automatically fix some issues and highlight others for manual adjustment.
6565

66-
5. Create a new branch for your changes ::
66+
5. Create a new branch for your changes. It's good practice to either give the branch a descriptive name or directly reference an issue number ::
6767

68-
git checkout -b feature/your-feature-name
68+
git checkout -b feature/issue-number
6969

7070
6. Make your changes. ::
7171

@@ -78,11 +78,22 @@ version.
7878

7979
7. Push your changes to your fork or branch ::
8080

81-
git push origin feature/your-feature-name
81+
git push origin feature/issue-number
82+
83+
8. Open a pull request on GitHub to the master branch of the upstream repository. Ensure your pull request:
84+
85+
- Has an informative title.
86+
- Links to any relevant issues.
87+
- Includes a clear description of the changes made.
88+
- Explains how a reviewer can test the changes.
89+
90+
.. note::
91+
It's good practice to open a draft pull request early in the development process to facilitate discussion and feedback, ensure there are no merge conflicts, and allow for continuous integration testing via GitHub Actions.
8292

83-
8. Open a pull request on GitHub to the master branch of the upstream repository, describing your changes and linking to any relevant issues.
8493
9. Core developers will review your changes, provide feedback, and merge them into the master branch if they meet the project's standards.
8594

95+
10. Once your pull request is merged, delete your branch on GitHub (a button should appear to do this automatically).
96+
8697
Testing your changes
8798
--------------------
8899

doc/index.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ We recommended most new users install the PyGambit Python package and read the a
6060
:hidden:
6161
:maxdepth: 1
6262

63-
intro
6463
install
6564
pygambit
6665
tools

doc/intro.rst

Lines changed: 0 additions & 179 deletions
This file was deleted.

doc/tutorials/interoperability_tutorials/openspiel.ipynb

Lines changed: 70 additions & 45 deletions
Large diffs are not rendered by default.

src/core/util.h

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <algorithm>
3131
#include <numeric>
3232
#include <map>
33+
#include <optional>
3334

3435
namespace Gambit {
3536

@@ -102,8 +103,9 @@ template <class C> class EnumerateView {
102103

103104
template <class C> auto enumerate(C &p_range) { return EnumerateView<C>(p_range); }
104105

105-
/// @brief A container adaptor which skips over a given value when iterating
106-
template <typename Container, typename T> class exclude_value {
106+
/// @brief A container adaptor which returns only the elements matching the predicate
107+
/// This is intended to look forward to C++20-style ranges
108+
template <typename Container, typename Pred> class filter_if {
107109
public:
108110
using Iter = decltype(std::begin(std::declval<Container &>()));
109111

@@ -115,10 +117,10 @@ template <typename Container, typename T> class exclude_value {
115117
using reference = typename std::iterator_traits<Iter>::reference;
116118
using pointer = typename std::iterator_traits<Iter>::pointer;
117119

118-
iterator(Iter current, Iter end, const T &value)
119-
: m_current(current), m_end(end), m_value(value)
120+
iterator(Iter current, Iter end, Pred pred)
121+
: m_current(current), m_end(end), m_pred(std::move(pred))
120122
{
121-
skip_if_value();
123+
advance_next_valid();
122124
}
123125

124126
value_type operator*() const { return *m_current; }
@@ -127,7 +129,7 @@ template <typename Container, typename T> class exclude_value {
127129
iterator &operator++()
128130
{
129131
++m_current;
130-
skip_if_value();
132+
advance_next_valid();
131133
return *this;
132134
}
133135

@@ -143,25 +145,22 @@ template <typename Container, typename T> class exclude_value {
143145
return a.m_current == b.m_current;
144146
}
145147

146-
friend bool operator!=(const iterator &a, const iterator &b)
147-
{
148-
return a.m_current != b.m_current;
149-
}
148+
friend bool operator!=(const iterator &a, const iterator &b) { return !(a == b); }
150149

151150
private:
152151
Iter m_current, m_end;
153-
T m_value;
152+
Pred m_pred;
154153

155-
void skip_if_value()
154+
void advance_next_valid()
156155
{
157-
while (m_current != m_end && *m_current == m_value) {
156+
while (m_current != m_end && !m_pred(*m_current)) {
158157
++m_current;
159158
}
160159
}
161160
};
162161

163-
exclude_value(const Container &c, const T &value)
164-
: m_begin(c.begin(), c.end(), value), m_end(c.end(), c.end(), value)
162+
filter_if(const Container &c, Pred pred)
163+
: m_begin(c.begin(), c.end(), pred), m_end(c.end(), c.end(), pred)
165164
{
166165
}
167166

@@ -172,6 +171,60 @@ template <typename Container, typename T> class exclude_value {
172171
iterator m_begin, m_end;
173172
};
174173

174+
template <typename Value, typename Range> class prepend_value {
175+
public:
176+
using Iter = decltype(std::begin(std::declval<Range &>()));
177+
178+
class iterator {
179+
public:
180+
using iterator_category = std::forward_iterator_tag;
181+
;
182+
using value_type = Value;
183+
using difference_type = std::ptrdiff_t;
184+
using reference = Value;
185+
using pointer = Value;
186+
187+
iterator(std::optional<Value> first, Iter current, Iter end)
188+
: m_first(std::move(first)), m_current(current), m_end(end)
189+
{
190+
}
191+
192+
reference operator*() const { return m_first ? *m_first : *m_current; }
193+
194+
iterator &operator++()
195+
{
196+
if (m_first) {
197+
m_first.reset();
198+
}
199+
else {
200+
++m_current;
201+
}
202+
return *this;
203+
}
204+
205+
bool operator==(const iterator &other) const
206+
{
207+
return m_first == other.m_first && m_current == other.m_current;
208+
}
209+
210+
bool operator!=(const iterator &other) const { return !(*this == other); }
211+
212+
private:
213+
std::optional<Value> m_first;
214+
Iter m_current, m_end;
215+
};
216+
217+
prepend_value(Value first, Range range) : m_first(first), m_range(std::move(range)) {}
218+
219+
iterator begin() const { return {m_first, std::begin(m_range), std::end(m_range)}; }
220+
221+
iterator end() const { return {std::nullopt, std::end(m_range), std::end(m_range)}; }
222+
223+
private:
224+
Value m_first;
225+
Range m_range;
226+
};
227+
175228
/// @brief Returns the maximum value of the function over the *non-empty* container
176229
template <class Container, class Func>
177230
auto maximize_function(const Container &p_container, const Func &p_function)

0 commit comments

Comments
 (0)