Skip to content

Commit

Permalink
#34: add explicit for constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
yosupo06 committed Jan 17, 2021
1 parent 77e3a0b commit 6c88a70
Show file tree
Hide file tree
Showing 14 changed files with 22 additions and 14 deletions.
2 changes: 1 addition & 1 deletion atcoder/dsu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace atcoder {
struct dsu {
public:
dsu() : _n(0) {}
dsu(int n) : _n(n), parent_or_size(n, -1) {}
explicit dsu(int n) : _n(n), parent_or_size(n, -1) {}

int merge(int a, int b) {
assert(0 <= a && a < _n);
Expand Down
2 changes: 1 addition & 1 deletion atcoder/fenwicktree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ template <class T> struct fenwick_tree {

public:
fenwick_tree() : _n(0) {}
fenwick_tree(int n) : _n(n), data(n) {}
explicit fenwick_tree(int n) : _n(n), data(n) {}

void add(int p, T x) {
assert(0 <= p && p < _n);
Expand Down
2 changes: 1 addition & 1 deletion atcoder/internal_csr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace internal {
template <class E> struct csr {
std::vector<int> start;
std::vector<E> elist;
csr(int n, const std::vector<std::pair<int, E>>& edges)
explicit csr(int n, const std::vector<std::pair<int, E>>& edges)
: start(n + 1), elist(edges.size()) {
for (auto e : edges) {
start[e.first + 1]++;
Expand Down
2 changes: 1 addition & 1 deletion atcoder/internal_math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct barrett {
unsigned long long im;

// @param m `1 <= m < 2^31`
barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}
explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

// @return m
unsigned int umod() const { return _m; }
Expand Down
2 changes: 1 addition & 1 deletion atcoder/internal_scc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace internal {
// Depth-First Search and Linear Graph Algorithms
struct scc_graph {
public:
scc_graph(int n) : _n(n) {}
explicit scc_graph(int n) : _n(n) {}

int num_vertices() { return _n; }

Expand Down
4 changes: 2 additions & 2 deletions atcoder/lazysegtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ template <class S,
struct lazy_segtree {
public:
lazy_segtree() : lazy_segtree(0) {}
lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
log = internal::ceil_pow2(_n);
size = 1 << log;
d = std::vector<S>(2 * size, e());
Expand Down
2 changes: 1 addition & 1 deletion atcoder/maxflow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace atcoder {
template <class Cap> struct mf_graph {
public:
mf_graph() : _n(0) {}
mf_graph(int n) : _n(n), g(n) {}
explicit mf_graph(int n) : _n(n), g(n) {}

int add_edge(int from, int to, Cap cap) {
assert(0 <= from && from < _n);
Expand Down
2 changes: 1 addition & 1 deletion atcoder/mincostflow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace atcoder {
template <class Cap, class Cost> struct mcf_graph {
public:
mcf_graph() {}
mcf_graph(int n) : _n(n) {}
explicit mcf_graph(int n) : _n(n) {}

int add_edge(int from, int to, Cap cap, Cost cost) {
assert(0 <= from && from < _n);
Expand Down
2 changes: 1 addition & 1 deletion atcoder/modint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ template <int id> struct dynamic_modint : internal::modint_base {
static internal::barrett bt;
static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
Expand Down
2 changes: 1 addition & 1 deletion atcoder/scc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace atcoder {
struct scc_graph {
public:
scc_graph() : internal(0) {}
scc_graph(int n) : internal(n) {}
explicit scc_graph(int n) : internal(n) {}

void add_edge(int from, int to) {
int n = internal.num_vertices();
Expand Down
4 changes: 2 additions & 2 deletions atcoder/segtree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace atcoder {
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
public:
segtree() : segtree(0) {}
segtree(int n) : segtree(std::vector<S>(n, e())) {}
segtree(const std::vector<S>& v) : _n(int(v.size())) {
explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
log = internal::ceil_pow2(_n);
size = 1 << log;
d = std::vector<S>(2 * size, e());
Expand Down
2 changes: 1 addition & 1 deletion atcoder/twosat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace atcoder {
struct two_sat {
public:
two_sat() : _n(0), scc(0) {}
two_sat(int n) : _n(n), _answer(n), scc(2 * n) {}
explicit two_sat(int n) : _n(n), _answer(n), scc(2 * n) {}

void add_clause(int i, bool f, int j, bool g) {
assert(0 <= i && i < _n);
Expand Down
4 changes: 4 additions & 0 deletions document_en/appendix.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ vector<long long> c = convolution<924844033>(a, b);
In the first case, $m$ is automatically set to be $998244353$.
In the second case, $m$ becomes the value that is explicitly specified, which is $924844033$ here.

### 💻 explicit specifier

Constructors of structs except `modint` are declared with the explicit specifier.

## Precise requirements in Segtree / LazySegtree

In some situations, the cardinality of algebraic structures for Segtree / LazySegtree would be infinite. In precise meaning, it may break the constraints in the document.
Expand Down
4 changes: 4 additions & 0 deletions document_ja/appendix.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ vector<long long> c = convolution<924844033>(a, b);
上段のように使った場合は、$m$ の値は自動的に $998244353$ となります。
下段のように使った場合は、$m$ の値は明示的に与えた値 (この場合は $924844033$) となります。

### 💻 explicit 指定子

`modint` 以外の構造体のコンストラクタには explicit が付いています。

## Segtree / LazySegtree の厳密な要件

Segtree / LazySegtree を使いたい状況において、扱う代数構造が無限集合である場合があります。たとえば、与えられた区間の $\mathrm{max}$ を求める、与えられた区間内の全ての要素に定数を足す、の二種類のクエリに対応する LazySegtree はよくありますが、このときたとえば $S = \mathrm{int}$ としてしまうと、$S$ は加法について閉じていない (overflow を起こす可能性がある) ため、厳密な意味でドキュメント本編の制約を満たしません。そこで、AC Library では以下のような場合正しく動くことを保証しています。
Expand Down

0 comments on commit 6c88a70

Please sign in to comment.