This documentation is automatically generated by online-judge-tools/verification-helper modified by bayashi_cl
#include "byslib/extension/irange.hpp"
#pragma once
#include "subrange.hpp"
/**
* @file irange.hpp
* @brief Python::range
*
* Python再現シリーズ range編
* See: https://docs.python.org/ja/3/library/stdtypes.html#range
*/
namespace bys {
template <class T> class IntegerIncrementIterator {
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T;
using pointer = T*;
using iterator_category = std::bidirectional_iterator_tag;
explicit IntegerIncrementIterator(T x) : value(x) {}
reference operator*() noexcept { return value; }
const reference operator*() const noexcept { return value; }
auto operator++() noexcept {
++value;
return *this;
}
auto operator++(int) noexcept {
auto temp = *this;
++*this;
return temp;
}
auto operator--() noexcept {
--value;
return *this;
}
auto operator--(int) {
auto temp = *this;
--*this;
return temp;
}
bool operator!=(IntegerIncrementIterator const& other) const { return value != other.value; }
bool operator==(IntegerIncrementIterator const& other) const { return value == other.value; }
private:
value_type value;
};
template <class T> class IntegerStepIterator {
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T;
using pointer = T*;
using iterator_category = std::bidirectional_iterator_tag;
explicit IntegerStepIterator(T f, T x, T s) : start(f), value(x), step(s) {}
reference operator*() noexcept { return start + value * step; }
const reference operator*() const noexcept { return start + value * step; }
auto operator++() {
++value;
return *this;
}
auto operator++(int) {
auto temp = *this;
++*this;
return temp;
}
auto operator--() {
--value;
return *this;
}
auto operator--(int) {
auto temp = *this;
--*this;
return temp;
}
bool operator!=(IntegerStepIterator const& other) const { return value != other.value; }
bool operator==(IntegerStepIterator const& other) const { return value == other.value; }
private:
value_type start, value, step;
};
template <class T> SubRange<IntegerIncrementIterator<T>> irange(T stop) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerIncrementIterator<T>;
if (stop < static_cast<T>(0)) stop = static_cast<T>(0);
return SubRange(iterator_t(static_cast<T>(0)), iterator_t(stop));
}
template <class T> SubRange<IntegerIncrementIterator<T>> irange(T start, T stop) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerIncrementIterator<T>;
if (stop < start) stop = start;
return SubRange(iterator_t(start), iterator_t(stop));
}
template <class T> SubRange<IntegerStepIterator<T>> irange(T start, T stop, T step) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerStepIterator<T>;
assert(step != 0);
auto w = step >= 0 ? stop - start : start - stop;
auto s = step >= 0 ? step : -step;
if (w < 0) w = 0;
return SubRange(iterator_t(start, static_cast<T>(0), step), iterator_t(start, (w + s - 1) / s, step));
}
} // namespace bys
#include <cstddef>
#include <iterator>
#include <vector>
#include <array>
#include <iostream>
#include <type_traits>
#include <cstdint>
namespace bys {
using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using u128 = __uint128_t;
using f32 = float;
using f64 = double;
using f128 = long double;
using isize = std::ptrdiff_t;
using usize = std::size_t;
#define DEFINE_NUM_LITERAL(name, type) \
constexpr auto operator"" name(unsigned long long x) { return static_cast<type>(x); }
DEFINE_NUM_LITERAL(_i8, std::int8_t);
DEFINE_NUM_LITERAL(_i16, std::int16_t);
DEFINE_NUM_LITERAL(_i32, std::int32_t);
DEFINE_NUM_LITERAL(_i64, std::int64_t);
DEFINE_NUM_LITERAL(_i128, __int128_t);
DEFINE_NUM_LITERAL(_u8, std::uint8_t);
DEFINE_NUM_LITERAL(_u16, std::uint16_t);
DEFINE_NUM_LITERAL(_u32, std::uint32_t);
DEFINE_NUM_LITERAL(_u64, std::uint64_t);
DEFINE_NUM_LITERAL(_u128, __uint128_t);
DEFINE_NUM_LITERAL(_z, std::size_t);
#undef DEFINE_NUM_LITERAL
} // namespace bys
/**
* @file traits.hpp
* @brief Types
*
* type_traits拡張
*/
namespace bys {
template <class, class = void> struct has_rshift_from_istream : std::false_type {};
template <class T>
struct has_rshift_from_istream<T, std::void_t<decltype(std::declval<std::istream&>() >> std::declval<T&>())>> : std::true_type {};
template <class T> constexpr bool has_rshift_from_istream_v = has_rshift_from_istream<T>::value;
template <class, class = void> struct has_lshift_to_ostream : std::false_type {};
template <class T>
struct has_lshift_to_ostream<T, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<T&>())>> : std::true_type {};
template <class T> constexpr bool has_lshft_to_ostream_v = has_lshift_to_ostream<T>::value;
template <class, class = void> struct is_tuple_like : std::false_type {};
template <class T> struct is_tuple_like<T, std::void_t<decltype(std::tuple_size<T>())>> : std::true_type {};
template <class T> constexpr bool is_tuple_like_v = is_tuple_like<T>::value;
template <class, class = void> struct is_iterable : std::false_type {};
template <class T> struct is_iterable<T, std::void_t<decltype(std::begin(std::declval<T>()))>> : std::true_type {};
template <class T> constexpr bool is_iterable_v = is_iterable<T>::value;
template <class T> struct Indexed {
static_assert(std::is_integral_v<T>);
using resolve_to = T;
};
using i32_1 = Indexed<i32>;
using i64_1 = Indexed<i64>;
template <class, class = void> struct is_indexed : std::false_type {};
template <class T> struct is_indexed<Indexed<T>> : std::true_type {};
template <class T> constexpr bool is_indexed_v = is_indexed<T>::value;
template <class T, class = void> struct resolve_type { using type = T; };
template <class T> struct resolve_type<T, std::void_t<typename T::resolve_to>> { using type = typename T::resolve_to; };
template <class T, std::size_t N> struct resolve_type<std::array<T, N>> {
using type = std::array<typename resolve_type<T>::type, N>;
};
template <class T, class U> struct resolve_type<std::pair<T, U>> {
using type = std::pair<typename resolve_type<T>::type, typename resolve_type<U>::type>;
};
template <class... Args> struct resolve_type<std::tuple<Args...>> {
using type = std::tuple<typename resolve_type<Args>::type...>;
};
template <class T> using resolve_type_t = typename resolve_type<T>::type;
} // namespace bys
namespace bys {
template <class Iterator> class SubRange {
public:
using iterator = Iterator;
using reverse_iterator = std::reverse_iterator<iterator>;
using value_type = typename iterator::value_type;
SubRange() = default;
SubRange(const SubRange& s) : _begin(s._begin), _end(s._end) {}
SubRange(const iterator& begin, const iterator& end) : _begin(begin), _end(end) {}
iterator begin() const noexcept { return _begin; }
iterator end() const noexcept { return _end; }
reverse_iterator rbegin() const noexcept { return reverse_iterator{_end}; }
reverse_iterator rend() const { return reverse_iterator{_begin}; }
auto operator[](std::size_t i) const noexcept { return *(_begin + i); }
auto size() const noexcept { return _end - _begin; }
bool empty() const noexcept { return _begin == _end; }
auto to_vec() const { return std::vector(_begin, _end); }
private:
iterator _begin, _end;
};
template <class Iterable> auto reversed(Iterable&& iter) {
static_assert(is_iterable_v<Iterable>, "iter is not iterable");
return SubRange(std::rbegin(std::forward<Iterable>(iter)), std::rend(std::forward<Iterable>(iter)));
}
} // namespace bys
/**
* @file irange.hpp
* @brief Python::range
*
* Python再現シリーズ range編
* See: https://docs.python.org/ja/3/library/stdtypes.html#range
*/
namespace bys {
template <class T> class IntegerIncrementIterator {
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T;
using pointer = T*;
using iterator_category = std::bidirectional_iterator_tag;
explicit IntegerIncrementIterator(T x) : value(x) {}
reference operator*() noexcept { return value; }
const reference operator*() const noexcept { return value; }
auto operator++() noexcept {
++value;
return *this;
}
auto operator++(int) noexcept {
auto temp = *this;
++*this;
return temp;
}
auto operator--() noexcept {
--value;
return *this;
}
auto operator--(int) {
auto temp = *this;
--*this;
return temp;
}
bool operator!=(IntegerIncrementIterator const& other) const { return value != other.value; }
bool operator==(IntegerIncrementIterator const& other) const { return value == other.value; }
private:
value_type value;
};
template <class T> class IntegerStepIterator {
public:
using difference_type = std::ptrdiff_t;
using value_type = T;
using reference = T;
using pointer = T*;
using iterator_category = std::bidirectional_iterator_tag;
explicit IntegerStepIterator(T f, T x, T s) : start(f), value(x), step(s) {}
reference operator*() noexcept { return start + value * step; }
const reference operator*() const noexcept { return start + value * step; }
auto operator++() {
++value;
return *this;
}
auto operator++(int) {
auto temp = *this;
++*this;
return temp;
}
auto operator--() {
--value;
return *this;
}
auto operator--(int) {
auto temp = *this;
--*this;
return temp;
}
bool operator!=(IntegerStepIterator const& other) const { return value != other.value; }
bool operator==(IntegerStepIterator const& other) const { return value == other.value; }
private:
value_type start, value, step;
};
template <class T> SubRange<IntegerIncrementIterator<T>> irange(T stop) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerIncrementIterator<T>;
if (stop < static_cast<T>(0)) stop = static_cast<T>(0);
return SubRange(iterator_t(static_cast<T>(0)), iterator_t(stop));
}
template <class T> SubRange<IntegerIncrementIterator<T>> irange(T start, T stop) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerIncrementIterator<T>;
if (stop < start) stop = start;
return SubRange(iterator_t(start), iterator_t(stop));
}
template <class T> SubRange<IntegerStepIterator<T>> irange(T start, T stop, T step) {
static_assert(std::is_integral_v<T>, "T is not integer.");
using iterator_t = IntegerStepIterator<T>;
assert(step != 0);
auto w = step >= 0 ? stop - start : start - stop;
auto s = step >= 0 ? step : -step;
if (w < 0) w = 0;
return SubRange(iterator_t(start, static_cast<T>(0), step), iterator_t(start, (w + s - 1) / s, step));
}
} // namespace bys