32#ifndef KBLIB_FAKESTD_H
33#define KBLIB_FAKESTD_H
43#if __has_include("gsl/pointers")
44# include "gsl/pointers"
48# define KBLIB_FAKESTD (__cplusplus < 201703L)
53template <
bool B,
typename T =
void>
57using decay_t =
typename std::decay<T>::type;
61 typename std::remove_reference<typename std::remove_cv<T>::type>::type;
66#if __cpp_lib_constexpr_functional
72template <
typename F,
typename... Args>
74 std::forward<F>(f), std::forward_as_tuple(std::forward<Args>(args)...))))
77 std::forward_as_tuple(std::forward<Args>(args)...));
84 template <
typename F,
typename... Args,
85 enable_if_t<not std::is_member_pointer<remove_cvref_t<F>>::value,
87 constexpr auto do_invoke(F&& f, Args&&... args)
noexcept(
noexcept(
88 std::forward<F>(f)(std::forward<Args>(args)...))) ->
decltype(
auto) {
89 return std::forward<F>(f)(std::forward<Args>(args)...);
92 template <
typename F,
typename Object,
typename... Args,
94 and std::is_member_function_pointer<F>::value,
96 constexpr auto do_invoke(F f, Object&& obj, Args&&... args)
noexcept(
97 noexcept((std::forward<Object>(obj).*f)(std::forward<Args>(args)...)))
99 return (obj.*f)(std::forward<Args>(args)...);
102 template <
typename F,
typename Pointer,
typename... Args,
104 and std::is_member_function_pointer<F>::value,
106 constexpr auto do_invoke(F f, Pointer ptr, Args&&... args)
noexcept(
107 noexcept((ptr->*f)(std::forward<Args>(args)...))) ->
decltype(
auto) {
108 return (ptr->*f)(std::forward<Args>(args)...);
111 template <
typename Member,
typename Object,
113 and std::is_member_object_pointer<Member>::value,
115 constexpr auto do_invoke(Member mem, Object&& obj)
noexcept
117 return std::forward<Object>(obj).*mem;
120 template <
typename Member,
typename Pointer,
122 and std::is_member_object_pointer<Member>::value,
124 constexpr auto do_invoke(Member mem, Pointer ptr)
noexcept
130template <
typename F,
typename... Args>
131constexpr auto invoke(F&& f, Args&&... args)
noexcept(
noexcept(
158 template <
typename AlwaysVoid,
typename,
typename...>
160 template <
typename F,
typename... Args>
162 std::declval<Args>()...))),
165 =
decltype(
invoke(std::declval<F>(), std::declval<Args>()...));
168 template <
class F,
class... ArgTypes>
171 template <
typename F,
typename... ArgTypes>
174 template <
typename... Ts>
178 template <
typename... Ts>
205 : std::integral_constant<
207 not std::is_same<decltype(is_referenceable_impl::test<Tp>(0)),
210 template <
class Tp,
class Up = Tp,
212 = not std::is_void<Tp>::value and not std::is_void<Up>::value>
214 template <
class LHS,
class RHS>
215 static decltype(
swap(std::declval<LHS>(), std::declval<RHS>()))
217 template <
class,
class>
221 using swap1 =
decltype((test_swap<Tp, Up>(0)));
222 using swap2 =
decltype((test_swap<Up, Tp>(0)));
224 static const bool value = not std::is_same<swap1, nat>::value
225 and not std::is_same<swap2, nat>::value;
228 template <
class Tp,
class Up>
231 template <
class Tp,
class Up = Tp,
235 swap(std::declval<Tp>(),
236 std::declval<Up>()))and
noexcept(
swap(std::declval<Up>(),
237 std::declval<Tp>()));
240 template <
class Tp,
class Up>
247 :
public std::integral_constant<bool,
248 detail::swappable_with<Tp&>::value> {};
252 :
public std::integral_constant<
253 bool, detail::nothrow_swappable_with<Tp&>::value> {};
257 template <
class Tp,
class Up>
259 :
public std::integral_constant<bool,
260 detail::swappable_with<Tp, Up>::value> {
265 :
public std::conditional<
266 detail::is_referenceable<Tp>::value,
267 is_swappable_with<typename std::add_lvalue_reference<Tp>::type,
268 typename std::add_lvalue_reference<Tp>::type>,
269 std::false_type>::type {};
271 template <
class Tp,
class Up>
273 :
public integral_constant<
274 bool, detail::nothrow_swappable_with<Tp, Up>::value> {};
278 :
public conditional<
279 detail::is_referenceable<Tp>::value,
280 is_nothrow_swappable_with<typename add_lvalue_reference<Tp>::type,
281 typename add_lvalue_reference<Tp>::type>,
282 false_type>::type {};
284 template <
class Tp,
class Up>
290 template <
class Tp,
class Up>
300 template <
typename F>
303 :
fd(
std::forward<F>(f)) {}
307 template <
class... Args>
309 not std::declval<invoke_result_t<std::decay_t<F>&, Args...>>()) {
310 return not
invoke(
fd, std::forward<Args>(args)...);
313 template <
class... Args>
314 constexpr auto operator()(Args&&... args)
const& ->
decltype(
317 return not
invoke(std::move(
fd), std::forward<Args>(args)...);
324 template <
typename F>
334 template <
class ForwardIt>
335 constexpr auto max_element(ForwardIt first, ForwardIt last) -> ForwardIt {
339 ForwardIt largest = first;
341 for (; first != last; ++first) {
342 if (*largest < *first) {
349 template <
class ForwardIt,
class Compare>
350 constexpr auto max_element(ForwardIt first, ForwardIt last, Compare comp)
355 ForwardIt largest = first;
357 for (; first != last; ++first) {
358 if (comp(*largest, *first)) {
366 constexpr auto size(
const C& c) ->
decltype(c.size()) {
370 template <
class T, std::
size_t N>
371 constexpr auto size(
const T (&)[N])
noexcept -> std::size_t {
379 template <
class Ret,
class Fp,
class... Args>
381 template <
class XFp,
class... XArgs>
384 std::declval<XArgs>()...));
385 template <
class XFp,
class... XArgs>
390 using type =
typename std::conditional<
391 not std::is_same<Result, detail::nat>::value,
392 typename std::conditional<std::is_void<Ret>::value, std::true_type,
393 std::is_convertible<Result, Ret>>
::type,
395 static const bool value = type::value;
397 template <
class Fp,
class... Args>
400 template <
bool IsInvokable,
bool IsCVVoid,
class Ret,
class Fp,
406 template <
class Ret,
class Fp,
class... Args>
413 static const bool value =
noexcept(ThisT::test_noexcept<Ret>(
414 kblib::invoke(std::declval<Fp>(), std::declval<Args>()...)));
417 template <
class Ret,
class Fp,
class... Args>
423 template <
class Ret,
class Fp,
class... Args>
426 std::is_void<Ret>::value, Ret, Fp, Args...>;
428 template <
class Fp,
class... Args>
433 template <
class Fp,
class... Args>
435 :
public std::enable_if<
436 invokable<Fp, Args...>::value,
437 typename invokable_r<void, Fp, Args...>::Result> {};
442 template <
class Fn,
class... Args>
444 : std::integral_constant<bool, detail::invokable<Fn, Args...>::value> {};
446 template <
class Ret,
class Fn,
class... Args>
448 : std::integral_constant<bool,
449 detail::invokable_r<Ret, Fn, Args...>::value> {
452 template <
class Fn,
class... Args>
455 template <
class Ret,
class Fn,
class... Args>
460 template <
class Fn,
class... Args>
462 : std::integral_constant<bool,
463 detail::nothrow_invokable<Fn, Args...>::value> {
466 template <
class Ret,
class Fn,
class... Args>
468 : std::integral_constant<
469 bool, detail::nothrow_invokable_r<Ret, Fn, Args...>::value> {};
471 template <
class Fn,
class... Args>
475 template <
class Ret,
class Fn,
class... Args>
481namespace fakestd =
std;
496template <
typename... Ts>
504template <
typename... Ts>
519template <
typename T,
typename =
void>
525template <
typename... T>
530 = std::integral_constant<
decltype(T::value), T::value>;
536template <
bool V,
typename T>
542template <
bool V,
typename T>
547 template <
typename F,
typename Arg,
typename =
void>
549 template <std::size_t... Is>
550 constexpr static auto do_apply(F&& f, Arg&& arg)
noexcept(
552 std::get<Is>(std::forward<Arg>(arg))...)))
555 std::get<Is>(std::forward<Arg>(arg))...);
561template <
typename F,
typename Arg>
562constexpr auto apply(F&& f, Arg&& arg)
noexcept(
564 std::forward<F>(f), std::forward<Arg>(arg),
565 std::index_sequence<std::tuple_size<Arg>::value>{})))
568 std::forward<F>(f), std::forward<Arg>(arg),
569 std::index_sequence<std::tuple_size<Arg>::value>{});
574 return std::unique_ptr<T>(p);
576template <
typename T,
typename D>
578 -> std::unique_ptr<T, D> {
579 return std::unique_ptr<T, D>(p, d);
587 return static_cast<std::make_unsigned_t<I>
>(x);
594 return static_cast<std::make_signed_t<I>
>(x);
601template <
typename A,
typename F>
604 and std::is_signed<A>::value,
605 std::make_signed_t<F>> {
613template <
typename A,
typename F>
615 -> enable_if_t<std::is_integral<A>::value and std::is_integral<F>::value
616 and std::is_unsigned<A>::value,
617 std::make_unsigned_t<F>> {
624 using yes = char (&)[1];
625 using no = char (&)[2];
627 template <
typename C>
628 static auto check(
decltype(&
C::swap)) -> yes;
630 static auto check(...) -> no;
633 constexpr static bool value =
sizeof(check<T>(
nullptr)) ==
sizeof(yes);
636template <
typename T,
typename =
void>
645 template <
typename... Ts>
646 constexpr auto ignore(Ts&&... ) noexcept ->
void {}
648 template <
typename T, std::size_t... Is>
651 noexcept(
ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)), 0)...)))
653 ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)), 0)...);
664 template <typename T, enable_if_t<not has_member_swap<T>::value
665 and not is_tuple_like<T>::value,
668 noexcept(std::is_nothrow_move_constructible<T>::value and
669 std::is_nothrow_move_assignable<T>::value) ->
void {
670 auto tmp = std::move(
a);
681 template <typename T, enable_if_t<has_member_swap<T>::value,
int> = 0>
683 noexcept(
noexcept(
a.swap(b))) ->
void {
693 template <
typename T, std::
size_t N>
694 KBLIB_UNUSED constexpr auto operator()(T (&
a)[N], T (&b)[N])
const
695 noexcept(std::is_nothrow_move_constructible<T>::value and
696 std::is_nothrow_move_assignable<T>::value) ->
void {
697 for (std::size_t i = 0; i < N; ++i) {
707 template <typename T, enable_if_t<is_tuple_like<T>::value
711 = std::tuple_size<T>::value>
712 KBLIB_UNUSED constexpr auto operator()(T&
a, T& b)
const noexcept(
noexcept(
718template <
typename T,
typename U = T>
720 T old_value = std::move(obj);
721 obj = std::forward<U>(new_value);
729 template <
typename T>
739 return (x & ~(x >> 1u));
742 template <
typename Num>
744 return static_cast<Num
>(
typename std::make_unsigned<Num>::type{1}
745 << (std::numeric_limits<Num>::digits - 1u));
748 template <
class... Args>
750 template <std::
size_t N>
751 using type =
typename std::tuple_element<N, std::tuple<Args...>>
::type;
754 template <auto K,
typename V>
756 constexpr static auto key = K;
760 template <
typename Key,
typename Comp,
typename... Vals>
763 template <std::
size_t I>
764 using element =
typename types::template type<I>;
766 template <Key key, std::
size_t I = 0>
768 static_assert(I <
sizeof...(Vals),
"key not found");
772 return get<key, I + 1>();
776 template <Key key,
typename Default =
void, std::
size_t I = 0>
778 if constexpr (I ==
sizeof...(Vals)) {
783 return get<key, I + 1>();
788 template <
typename N>
792 template <
typename T>
794 static_assert(max_val<T> < max_val<std::intmax_t>,
795 "Cannot safely promote intmax_t.");
797 template <
typename U>
808 using type =
typename decltype(
809 ints_map::template get_default<max_val<T> + 1>())
::type;
812 template <typename N, bool = std::is_signed<N>::value>
815 template <
typename N>
820 template <
typename N>
823 template <typename N, bool = std::is_unsigned<N>::value>
826 template <
typename N>
831 template <
typename N>
836template <
typename N,
typename =
void>
841 using type = std::conditional_t<
842 std::is_signed<N>::value, N,
857template <
typename C,
typename T,
858 bool = std::is_const<typename std::remove_reference<C>::type>::value>
861template <
typename C,
typename T>
864template <
typename C,
typename T>
867template <
typename C,
typename T>
870template <
typename C,
typename V>
873template <
typename T,
typename =
void>
878 using type =
typename T::value_type;
886template <
typename T,
typename =
void>
891 using type =
typename T::key_type;
899template <
typename T,
typename =
void>
904 using type =
typename T::mapped_type;
912template <
typename T,
typename =
void>
917 using type =
typename T::hasher;
925template <
typename Container,
bool = key_detected_v<Container>,
926 typename T =
typename Container::value_type>
929template <
typename Container>
931 :
meta_type<typename Container::value_type> {};
933template <
typename Container>
936template <
typename Container>
937constexpr static bool is_linear_container_v
938 = value_detected_v<Container> and not key_detected_v<Container>;
940template <
typename Container>
943template <
typename Container,
bool = key_detected_v<Container>,
944 bool = mapped_detected_v<Container>>
947template <
typename Container>
949 :
meta_type<typename Container::key_type> {};
951template <
typename Container>
954template <
typename Container>
955constexpr static bool is_setlike_v
957 Container> and value_detected_v<Container> and not mapped_detected_v<Container> and std::is_same<key_detected_t<Container>,
value_detected_t<Container>>::value);
959template <
class InputIt1,
class InputIt2>
961 InputIt2 first2) ->
bool {
962 for (; first1 != last1; ++first1, ++first2) {
963 if (not (*first1 == *first2)) {
970template <
typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
972 not std::is_same<InputIt2, BinaryPredicate>::value,
int> = 0>
974 InputIt2 first2, BinaryPredicate p)
976 for (; first1 != last1; ++first1, ++first2) {
977 if (not p(*first1, *first2)) {
983template <
class RandomIt1,
class RandomIt2,
985 std::is_base_of<std::random_access_iterator_tag,
986 typename std::iterator_traits<
987 RandomIt1>::iterator_category>::value
988 and std::is_base_of<std::random_access_iterator_tag,
989 typename std::iterator_traits<
990 RandomIt2>::iterator_category>::value,
993 RandomIt2 first2, RandomIt2 last2)
995 if (std::distance(first1, last1) == std::distance(first2, last2)) {
998 for (; first1 != last1; ++first1, ++first2) {
999 if (not (*first1 == *first2)) {
1006template <
class RandomIt1,
class RandomIt2,
typename BinaryPredicate,
1008 std::is_base_of<std::random_access_iterator_tag,
1009 typename std::iterator_traits<
1010 RandomIt1>::iterator_category>::value
1011 and std::is_base_of<std::random_access_iterator_tag,
1012 typename std::iterator_traits<
1013 RandomIt2>::iterator_category>::value,
1016 RandomIt2 first2, RandomIt2 last2,
1017 BinaryPredicate p) ->
bool {
1018 if (std::distance(first1, last1) == std::distance(first2, last2)) {
1021 for (; first1 != last1; ++first1, ++first2) {
1022 if (not p(*first1, *first2)) {
1029 class InputIt1,
class InputIt2,
1031 not std::is_base_of<
1032 std::random_access_iterator_tag,
1033 typename std::iterator_traits<InputIt1>::iterator_category>::value
1034 or not std::is_base_of<std::random_access_iterator_tag,
1035 typename std::iterator_traits<
1036 InputIt2>::iterator_category>::value,
1039 InputIt2 first2, InputIt2 last2) ->
bool {
1040 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1041 if (not (*first1 == *first2)) {
1045 return (first1 == last1 and first2 == last2);
1049 typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
1051 not std::is_base_of<
1052 std::random_access_iterator_tag,
1053 typename std::iterator_traits<InputIt1>::iterator_category>::value
1054 or not std::is_base_of<std::random_access_iterator_tag,
1055 typename std::iterator_traits<
1056 InputIt2>::iterator_category>::value,
1059 InputIt2 first2, InputIt2 last2,
1060 BinaryPredicate p) ->
bool {
1061 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1062 if (not p(*first1, *first2)) {
1066 return (first1 == last1 and first2 == last2);
1069template <
typename C>
1074template <
typename T, std::
size_t N>
1079template <
class InputIt1,
class InputIt2>
1083 InputIt2 last2) ->
bool {
1084 for (; (first1 != last1) and (first2 != last2); ++first1, (void)++first2) {
1085 if (*first1 < *first2)
1087 if (*first2 < *first1)
1090 return (first1 == last1) and (first2 != last2);
1094 template <
typename D,
typename T,
typename =
void>
1099 template <
typename D,
typename T>
1109template <
typename T>
1123 template <
typename... Args,
1126 : p{new T(args...)} {}
1127 template <
typename... Args,
1130 : p{new T{args...}} {}
1133 : p{(u.p ? (new T(*u.p)) : nullptr)} {}
1145 p.reset(
new T(*u.p));
1162 p.reset(
new T(val));
1168 p.reset(
new T(std::move(val)));
1171 auto assign() & ->
void { p.reset(
new T()); }
1172 auto assign(
const T& val) & ->
void { p.reset(
new T(val)); }
1173 auto assign(T&& val) & ->
void { p.reset(
new T(std::move(val))); }
1174 template <
typename... Args>
1176 p.reset(
new T(std::forward<Args>(args)...));
1178 template <
typename... Args>
1180 p.reset(
new T{std::forward<Args>(args)...});
1189 return p !=
nullptr;
1223 std::unique_ptr<element_type> p;
1226template <
typename T,
typename D>
1228 using Base = std::unique_ptr<T, D>;
1231 using typename Base::deleter_type;
1232 using typename Base::element_type;
1233 using typename Base::pointer;
1238 using Base::operator=;
1242 using Base::release;
1247 using Base::get_deleter;
1248 using Base::operator bool;
1250 using Base::operator*;
1251 using Base::operator->;
1265template <
typename T,
typename D>
1267 using Base = std::unique_ptr<T[], D>;
1270 using typename Base::deleter_type;
1271 using typename Base::element_type;
1272 using typename Base::pointer;
1277 using Base::operator=;
1281 using Base::release;
1286 using Base::get_deleter;
1287 using Base::operator bool;
1289 using Base::operator[];
auto value() const &noexcept -> const_reference
auto value() &&noexcept -> element_type &&
auto value() &noexcept -> reference
heap_value2 & operator=(const heap_value2 &other)
auto value() const &&noexcept -> const element_type &&
heap_value2(const heap_value2 &other)
const element_type & const_reference
auto value() &&noexcept -> element_type &&
heap_value2 & operator=(const heap_value2 &other)
heap_value2(const heap_value2 &other)
auto value() &noexcept -> reference
auto value() const &noexcept -> const_reference
auto value() const &&noexcept -> const element_type &&
decltype(*std::declval< pointer >()) reference
const element_type & const_reference
heap_value(heap_value &&u) noexcept
auto value() const &noexcept -> const_reference
auto assign(in_place_agg_t, Args &&... args) -> void
auto reset() noexcept -> void
auto operator=(const T &val) &-> heap_value &
auto get() const &noexcept -> const_pointer
constexpr heap_value() noexcept
auto value() &noexcept -> reference
auto operator=(T &&val) &-> heap_value &
auto assign(fakestd::in_place_t, Args &&... args) -> void
auto assign(T &&val) &-> void
heap_value(in_place_agg_t, Args &&... args)
constexpr auto swap(heap_value &other) noexcept -> void
auto operator=(heap_value &&u) &noexcept -> heap_value &
auto value() &&noexcept -> T &&
auto operator*() &noexcept -> reference
auto operator*() const &noexcept -> const_reference
auto operator*() const &&noexcept -> const T &&
constexpr heap_value(std::nullptr_t) noexcept
auto operator->() const &noexcept -> const_pointer
auto assign(const T &val) &-> void
auto operator->() &noexcept -> pointer
auto value() const &&noexcept -> const T &&
const T & const_reference
heap_value(const heap_value &u)
auto get() &noexcept -> pointer
auto operator*() &&noexcept -> T &&
heap_value(fakestd::in_place_t, Args &&... args)
auto operator=(const heap_value &u) &-> heap_value &
typename filter_unsigned< N >::type filter_unsigned_t
constexpr auto ignore(Ts &&...) noexcept -> void
constexpr auto msb_possible() -> Num
typename filter_signed< N >::type filter_signed_t
constexpr auto do_invoke(F &&f, Args &&... args) noexcept(noexcept(std::forward< F >(f)(std::forward< Args >(args)...))) -> decltype(auto)
constexpr std::intmax_t max_val
constexpr auto swap_tuple_impl(T &a, T &b, std::index_sequence< Is... >) noexcept(noexcept(ignore(((void) swap(std::get< Is >(a), std::get< Is >(b)), 0)...))) -> void
constexpr auto msb(std::uintmax_t x) -> std::uintmax_t
constexpr auto max_element(ForwardIt first, ForwardIt last) -> ForwardIt
constexpr bool is_swappable_v
auto not_fn(F &&f) -> detail::not_fn_t< F >
constexpr bool is_nothrow_swappable_with_v
typename invoke_result< F, ArgTypes... >::type invoke_result_t
typename make_void< Ts... >::type void_t
constexpr bool is_invocable_v
constexpr bool is_swappable_with_v
constexpr bool is_nothrow_swappable_v
constexpr bool is_nothrow_invocable_v
constexpr bool is_invocable_r_v
constexpr auto size(const C &c) -> decltype(c.size())
constexpr bool is_nothrow_invocable_r_v
constexpr struct kblib::nums::max_t max
The main namespace in which all entities from kblib are defined.
typename key_type_setlike< Container >::type key_type_setlike_t
constexpr auto exchange(T &obj, U &&new_value) -> T
constexpr auto size(const C &c) -> decltype(c.size())
constexpr bool mapped_detected_v
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)
std::integral_constant< decltype(T::value), T::value > metafunction_value_t
typename hash_detected< T >::type hash_detected_t
constexpr bool value_detected_v
auto get(punner< Types... > &p) noexcept -> decltype(auto)
constexpr auto invoke(F &&f, Args &&... args) noexcept(noexcept(detail::do_invoke(std::forward< F >(f), std::forward< Args >(args)...))) -> decltype(auto)
typename std::decay< T >::type decay_t
typename value_detected< T >::type value_detected_t
std::integral_constant< bool, v > bool_constant
constexpr bool key_detected_v
typename void_if< b >::type void_if_t
typename value_type_linear< Container >::type value_type_linear_t
typename key_detected< T >::type key_detected_t
constexpr auto signed_cast(F x) -> enable_if_t< std::is_integral< A >::value and std::is_integral< F >::value and std::is_signed< A >::value, std::make_signed_t< F > >
Cast argument to equivalently-sized type with the same signednessas the template parameter.
typename return_assert< V, T >::type return_assert_t
typename safe_signed< N >::type safe_signed_t
typename std::remove_reference< typename std::remove_cv< T >::type >::type remove_cvref_t
constexpr bool hash_detected_v
constexpr auto signed_promote(N x) noexcept -> safe_signed_t< N >
auto to_unique(gsl::owner< T * > p) -> std::unique_ptr< T >
typename mapped_detected< T >::type mapped_detected_t
constexpr auto lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) -> bool
constexpr struct kblib::in_place_agg_t in_place_agg
typename copy_const< C, V >::type copy_const_t
typename meta_type< Ts... >::type meta_type_t
constexpr auto to_unsigned(I x) -> std::make_unsigned_t< I >
Cast integral argument to corresponding unsigned type.
constexpr auto equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) -> bool
static constexpr auto do_apply(F &&f, Arg &&arg) noexcept(noexcept(kblib::invoke(std::forward< F >(f), std::get< Is >(std::forward< Arg >(arg))...))) -> decltype(auto)
constexpr auto operator()(U, U) noexcept -> bool
typename decltype(ints_map::template get_default< max_val< T >+1 >())::type type
typename std::tuple_element< N, std::tuple< Args... > >::type type
static constexpr auto key
static constexpr auto get_default() noexcept -> auto
static constexpr auto get() noexcept -> auto
typename types::template type< I > element
typename std::conditional< not std::is_same< Result, detail::nat >::value, typename std::conditional< std::is_void< Ret >::value, std::true_type, std::is_convertible< Result, Ret > >::type, std::false_type >::type type
static auto try_call(int) -> decltype(kblib::invoke(std::declval< XFp >(), std::declval< XArgs >()...))
static auto try_call(...) -> detail::nat
decltype(try_call< Fp, Args... >(0)) Result
decltype(invoke(std::declval< F >(), std::declval< Args >()...)) type
nat & operator=(const nat &)=delete
constexpr auto operator()(Args &&... args) const &-> decltype(not std::declval< invoke_result_t< std::decay_t< F > const &, Args... > >())
constexpr not_fn_t(F &&f)
constexpr not_fn_t(not_fn_t &&)=default
constexpr auto operator()(Args &&... args) &-> decltype(not std::declval< invoke_result_t< std::decay_t< F > &, Args... > >())
constexpr not_fn_t(const not_fn_t &)=default
static void test_noexcept(Tp) noexcept
decltype((test_swap< Up, Tp >(0))) swap2
static decltype(swap(std::declval< LHS >(), std::declval< RHS >())) test_swap(int)
decltype((test_swap< Tp, Up >(0))) swap1
static nat test_swap(long)
static constexpr bool value
typename T::key_type type
typename T::mapped_type type
Essentially just like std::enable_if, but with a different name that makes it clearer what it does in...
std::conditional_t< std::is_signed< N >::value, N, typename detail::next_larger_signed< std::make_signed_t< N > >::type > type
typename T::value_type type
Provides macros and basic templates used by the rest of kblib.
#define KBLIB_UNUSED
This internal macro is used to provide a fallback for [[maybe_unused]] in C++14.
#define KBLIB_NODISCARD
This internal macro is used to provide a fallback for [[nodiscard]] in C++14.