2019-10-06 16:45:29 +02:00
|
|
|
// -*- c++ -*-
|
|
|
|
/*
|
|
|
|
Students: please don't try to understand the details of headers just
|
|
|
|
yet. All will be explained. This header is primarily used so that you don't
|
|
|
|
have to understand every concept all at once.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <array>
|
|
|
|
#include <cmath>
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <fstream>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <iostream>
|
|
|
|
#include <iterator>
|
|
|
|
#include <list>
|
|
|
|
#include <memory>
|
|
|
|
#include <ostream>
|
|
|
|
#include <set>
|
|
|
|
#include <sstream>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <string>
|
|
|
|
#include <tuple>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <unordered_set>
|
|
|
|
#include <utility>
|
|
|
|
#include <valarray>
|
|
|
|
#include <vector>
|
|
|
|
|
2019-10-06 17:16:19 +02:00
|
|
|
#include "bits/soi-dbg.hpp"
|
2019-10-06 16:45:29 +02:00
|
|
|
|
|
|
|
namespace soi_h {
|
|
|
|
|
|
|
|
void check_for_eof() {
|
|
|
|
if (!(std::cin >> std::ws).eof())
|
|
|
|
std::cerr << "WARNING: didn't read the whole input\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void noninteractive_check_eof() {
|
|
|
|
// make symbol 0x1A (Ctrl+Z) a whitespace
|
|
|
|
struct console_ctype : std::ctype<char> {
|
|
|
|
static const mask* get_table() {
|
|
|
|
static const std::array<mask, table_size> table = []() {
|
|
|
|
std::array<mask, table_size> table;
|
|
|
|
std::copy(classic_table(), classic_table() + table_size, table.begin());
|
|
|
|
table['\x1a'] |= space;
|
|
|
|
return table;
|
|
|
|
}();
|
|
|
|
return table.data();
|
|
|
|
}
|
|
|
|
console_ctype(std::size_t refs = 0) : ctype(get_table(), false, refs) {}
|
|
|
|
};
|
|
|
|
std::cin.imbue(std::locale(std::cin.getloc(), new console_ctype));
|
|
|
|
check_for_eof();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool should_check_for_eof() {
|
2019-10-06 17:16:19 +02:00
|
|
|
if (const char* eofcheck_enabled = std::getenv("SOI_EOFCHECK")) {
|
2019-10-06 16:45:29 +02:00
|
|
|
if (!std::strcmp(eofcheck_enabled, "1"))
|
|
|
|
return true;
|
|
|
|
if (!std::strcmp(eofcheck_enabled, "0"))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void initialize_debug() {
|
|
|
|
std::cout << std::unitbuf; // enable automatic flushing
|
|
|
|
std::cin.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
|
|
std::ios::sync_with_stdio(false);
|
|
|
|
|
|
|
|
if (should_check_for_eof() &&
|
|
|
|
std::atexit(noninteractive_check_eof) != 0) {
|
|
|
|
std::cerr << "WARNING: soi.h -- registration of sanity check at exit failed\n";
|
|
|
|
}
|
|
|
|
soi_h::detail::dbg_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct soi_h_initializer {
|
|
|
|
soi_h_initializer(bool release) {
|
|
|
|
if (release) {
|
|
|
|
std::ios::sync_with_stdio(false);
|
|
|
|
std::cin.tie(0);
|
|
|
|
} else {
|
|
|
|
initialize_debug();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef SOI_RELEASE
|
|
|
|
soi_h_initializer soi_h_initializer_{true};
|
|
|
|
#else
|
|
|
|
soi_h_initializer soi_h_initializer_{false};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} // end namespace soi_h
|
|
|
|
|
2019-10-06 17:16:19 +02:00
|
|
|
#include "bits/soi-deprecate.hpp"
|
2019-10-06 16:45:29 +02:00
|
|
|
|
|
|
|
#define int int64_t
|
|
|
|
using namespace std;
|
|
|
|
|