40#include <initializer_list>
45#define KBLIB_DEBUG_LOG_RANGES 0
46#if KBLIB_DEBUG_LOG_RANGES
52namespace detail_simple {
62 return (r.
low <= v) and (v < r.
high);
66 return (r.
low <= v) and (v <= r.
high);
71template <
typename... Ts>
72constexpr bool any_void = (std::is_void_v<Ts> or ...);
74template <
typename F,
typename... T>
78 not any_void<decltype(kblib::apply(f, std::forward<T>(t)))...>,
79 decltype(std::tuple{
kblib::apply(f, std::forward<T>(t))...})> {
80 return std::tuple{
kblib::apply(f, std::forward<T>(t))...};
83template <
typename F,
typename... T>
84auto map(F f, T&&... t)
noexcept(
85 noexcept((
static_cast<void>(
kblib::apply(f, std::forward<T>(t))), ...)))
86 -> enable_if_t<any_void<decltype(kblib::apply(f, std::forward<T>(t)))...>,
88 (
static_cast<void>(
kblib::apply(f, std::forward<T>(t))), ...);
121template <
typename BinaryOperation>
123 return [](
auto&&
a,
auto&& b) {
124 return BinaryOperation{}(
static_cast<decltype(b)
>(b),
125 static_cast<decltype(
a)
>(
a));
137template <
typename BinaryOperation>
139 return [op = std::move(op)](
auto&&
a,
auto&& b) {
140 return op(
static_cast<decltype(b)
>(b),
static_cast<decltype(
a)
>(
a));
144template <
typename T, std::
size_t N>
150 return (array[1] - array[0]) == 1;
152 for (std::size_t i = 1; i < N; ++i) {
153 if ((array[i] - array[i - 1]) != 1) {
167 const std::bitset<std::numeric_limits<std::uintmax_t>::digits> val)
noexcept
169 for (
auto i : range<int>(
to_signed(val.size()) - 1, 0, -1)) {
176template <std::size_t
size,
typename T,
typename... Ts>
181template <std::
size_t size,
typename T>
185template <std::u
intmax_t I>
188 unsigned short,
unsigned int,
unsigned long,
189 unsigned long long, std::uintmax_t>::type;
191template <std::u
intmax_t I>
194 signed short,
signed int,
signed long,
195 signed long long, std::uintmax_t>::type;
197template <std::u
intmax_t I>
200template <std::u
intmax_t I>
207 template <
typename T>
209 return static_cast<T&&
>(in);
218 return std::forward<T>(in);
236template <
typename LeftContainer,
typename RightContainer>
237auto arraycat(LeftContainer A, RightContainer&& B)
noexcept(
238 noexcept(A.insert(A.end(), B.begin(), B.end()))
239 and std::is_nothrow_move_constructible<LeftContainer>::value)
241 A.insert(A.end(), B.begin(), B.end());
264concept zero_constructible =
requires(T t) {
269 consteval zero_t(
int i) { i == 0 ? void() : throw 0; }
270 template <zero_constructible T>
271 constexpr operator T() const noexcept {
274 explicit constexpr operator std::nullptr_t() const noexcept {
283#undef KBLIB_DEBUG_LOG_RANGES
This file provides some iterators, ranges, iterator/range adapters, and operations that can be perfor...
constexpr auto size(const C &c) -> decltype(c.size())
typename first_bigger_than< 1+(filg2(I)+1)/CHAR_BIT, signed char, signed short, signed int, signed long, signed long long, std::uintmax_t >::type int_smallest
constexpr auto in_range(const T &v, detail_simple::simple_range< T > r)
constexpr auto is_consecutive(const T(&array)[N]) -> enable_if_t< std::is_integral< T >::value, bool >
auto map(F f, T &&... t) noexcept(noexcept(std::tuple{ kblib::apply(f, std::forward< T >(t))...})) -> enable_if_t< not any_void< decltype(kblib::apply(f, std::forward< T >(t)))... >, decltype(std::tuple{kblib::apply(f, std::forward< T >(t))...})>
constexpr auto to_signed(I x) -> std::make_signed_t< I >
Cast integral argument to corresponding signed type.
constexpr auto a(const std::initializer_list< T > &a) -> auto
Index an array literal without naming its type.
typename std::enable_if< B, T >::type enable_if_t
constexpr auto apply(F &&f, Arg &&arg) noexcept(noexcept(detail::apply_impl< F, Arg >::do_apply(std::forward< F >(f), std::forward< Arg >(arg), std::index_sequence< std::tuple_size< Arg >::value >{}))) -> decltype(auto)
auto arraycat(LeftContainer A, RightContainer &&B) noexcept(noexcept(A.insert(A.end(), B.begin(), B.end())) and std::is_nothrow_move_constructible< LeftContainer >::value) -> LeftContainer
Concatenate two dynamic containers together.
typename int_smallest< I >::type int_smallest_t
constexpr auto filg2(const std::bitset< std::numeric_limits< std::uintmax_t >::digits > val) noexcept -> int
Floored integer binary logarithm. Returns floor(lb(val)).
auto safe_auto(T &in) -> T &
Safely propagate an xvalue or lvalue without dangling references.
constexpr auto flip(BinaryOperation op) -> auto
Transforms a binary operation into one which takes reversed arguments.
typename first_bigger_than< 1+filg2(I)/CHAR_BIT, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, std::uintmax_t >::type uint_smallest
typename uint_smallest< I >::type uint_smallest_t
constexpr auto to_unsigned(I x) -> std::make_unsigned_t< I >
Cast integral argument to corresponding unsigned type.
constexpr auto in_range_i(const T &v, detail_simple::simple_range< T > r)
RAII_wrapper(const RAII_wrapper &)=delete
RAII_wrapper & operator=(const RAII_wrapper &)=delete
RAII_wrapper(const T &t_)
RAII_wrapper(RAII_wrapper &&)=delete
~RAII_wrapper() noexcept(noexcept(t()))
RAII_wrapper & operator=(RAII_wrapper &&)=delete
The identity function, as a function object.
auto operator()(T &&in) -> T &&
#define KBLIB_NODISCARD
This internal macro is used to provide a fallback for [[nodiscard]] in C++14.