107 lines
3.1 KiB
C++
107 lines
3.1 KiB
C++
// Copyright Johannes Kapfhammer 2019-2022.
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
#ifndef SOI_HEADER_IO
|
|
#define SOI_HEADER_IO
|
|
|
|
#include <iostream>
|
|
#include <cassert>
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
template <typename T>
|
|
T read() {
|
|
T x;
|
|
std::cin >> x;
|
|
return x;
|
|
}
|
|
|
|
template <typename T1, typename T2>
|
|
std::pair<T1, T2> read() {
|
|
return std::pair<T1, T2>{read<T1>(), read<T2>()};
|
|
}
|
|
template <typename T1, typename T2, typename T3, typename... Ts>
|
|
std::tuple<T1, T2, T3, Ts...> read() {
|
|
return std::tuple<T1, T2, T3, Ts...>{read<T1>(), read<T2>(), read<T3>(), read<Ts>()...};
|
|
}
|
|
|
|
int64_t read_int() { return read<int64_t>(); }
|
|
char read_char() { return read<char>(); }
|
|
double read_double() { return read<double>(); }
|
|
std::string read_string() { return read<std::string>(); }
|
|
template <typename T>
|
|
std::vector<T> read_vector(int n) {
|
|
assert(n >= 0);
|
|
std::vector<T> v;
|
|
v.reserve(n);
|
|
std::generate_n(std::back_inserter(v), n, read<T>);
|
|
return v;
|
|
}
|
|
|
|
namespace soi {
|
|
|
|
namespace io {
|
|
|
|
template <typename T, typename TChar, typename TCharTraits>
|
|
inline typename std::enable_if<!::soi::prettyprint::is_container<T>::value,
|
|
std::basic_ostream<TChar, TCharTraits> &>::type
|
|
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x) {
|
|
return stream << x;
|
|
}
|
|
|
|
template <typename TChar, typename TCharTraits>
|
|
inline std::basic_ostream<TChar, TCharTraits>&
|
|
print(std::basic_ostream<TChar, TCharTraits> &stream, std::string const& x) {
|
|
return stream << x;
|
|
}
|
|
|
|
template <typename TChar, typename TCharTraits>
|
|
std::basic_ostream<TChar, TCharTraits> &
|
|
print(std::basic_ostream<TChar, TCharTraits> &stream, const bool &x) {
|
|
return stream << (x ? "true" : "false");
|
|
}
|
|
|
|
struct space_separated_delims {
|
|
static const ::soi::prettyprint::delimiters_values<char> values;
|
|
};
|
|
const ::soi::prettyprint::delimiters_values<char> space_separated_delims::values = { "", " ", "" };
|
|
|
|
template <typename T, typename TChar, typename TCharTraits>
|
|
inline typename std::enable_if<::soi::prettyprint::is_container<T>::value,
|
|
std::basic_ostream<TChar, TCharTraits> &>::type
|
|
print(std::basic_ostream<TChar, TCharTraits> &stream, const T &x) {
|
|
return ::soi::prettyprint::pretty_print(stream,
|
|
soi::prettyprint::custom_delims<space_separated_delims>(x));
|
|
}
|
|
|
|
template <typename T, typename TChar, typename TCharTraits>
|
|
void print_with_space(std::basic_ostream<TChar, TCharTraits> &stream, T&& x) {
|
|
stream << ' ';
|
|
::soi::io::print(stream, std::forward<T>(x));
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
template <typename Arg, typename... Args>
|
|
void print(Arg&& arg, Args&&... args) {
|
|
soi::io::print(std::cout, arg);
|
|
using expander = bool[];
|
|
(void)expander{0, (soi::io::print_with_space(std::cout, std::forward<Args>(args)), false)...};
|
|
std::cout << '\n';
|
|
}
|
|
|
|
void print() {
|
|
std::cout << '\n';
|
|
}
|
|
|
|
template <typename... Args>
|
|
void print_no_space(Args&&... args) {
|
|
using expander = bool[];
|
|
(void)expander{0, (soi::io::print(std::cout, std::forward<Args>(args)), false)...};
|
|
}
|
|
|
|
#endif // SOI_HEADER_IO
|