32#ifndef KBLIB_FAKESTD_H
33#define KBLIB_FAKESTD_H
44#if __has_include("gsl/pointers")
45# include "gsl/pointers"
49# define KBLIB_FAKESTD (__cplusplus < 201703L)
54#if __has_include("gsl/pointers")
61template <
bool B,
typename T =
void>
65using decay_t =
typename std::decay<T>::type;
69 typename std::remove_reference<typename std::remove_cv<T>::type>::type;
74#if __cpp_lib_constexpr_functional
80template <
typename F,
typename... Args>
83 std::forward_as_tuple(std::forward<Args>(args)...)))) ->
decltype(
auto) {
85 std::forward_as_tuple(std::forward<Args>(args)...));
93 typename F,
typename... Args,
94 enable_if_t<not std::is_member_pointer<remove_cvref_t<F>>
::value,
int>
96 constexpr auto do_invoke(F&& f, Args&&... args)
noexcept(
noexcept(
97 std::forward<F>(f)(std::forward<Args>(args)...))) ->
decltype(
auto) {
98 return std::forward<F>(f)(std::forward<Args>(args)...);
101 template <
typename F,
typename Object,
typename... Args,
106 constexpr auto do_invoke(F f, Object&& obj, Args&&... args)
noexcept(
107 noexcept((std::forward<Object>(obj)
108 .*f)(std::forward<Args>(args)...))) ->
decltype(
auto) {
109 return (obj.*f)(std::forward<Args>(args)...);
112 template <
typename F,
typename Pointer,
typename... Args,
117 constexpr auto do_invoke(F f, Pointer ptr, Args&&... args)
noexcept(
118 noexcept((ptr->*f)(std::forward<Args>(args)...))) ->
decltype(
auto) {
119 return (ptr->*f)(std::forward<Args>(args)...);
122 template <
typename Member,
typename Object,
128 Object&& obj)
noexcept ->
decltype(
auto) {
129 return std::forward<Object>(obj).*mem;
132 template <
typename Member,
typename Pointer,
138 Pointer ptr)
noexcept ->
decltype(
auto) {
143template <
typename F,
typename... Args>
144constexpr auto invoke(F&& f, Args&&... args)
noexcept(
noexcept(
146 std::forward<Args>(args)...))) ->
decltype(
auto) {
171 template <
typename AlwaysVoid,
typename,
typename...>
173 template <
typename F,
typename... Args>
175 std::declval<Args>()...))),
178 =
decltype(
invoke(std::declval<F>(), std::declval<Args>()...));
181 template <
class F,
class... ArgTypes>
184 template <
typename F,
typename... ArgTypes>
187 template <
typename... Ts>
191 template <
typename... Ts>
218 : std::integral_constant<
220 not std::is_same<decltype(is_referenceable_impl::test<Tp>(0)),
223 template <
class Tp,
class Up = Tp,
227 template <
class LHS,
class RHS>
228 static decltype(
swap(std::declval<LHS>(), std::declval<RHS>()))
230 template <
class,
class>
234 using swap1 =
decltype((test_swap<Tp, Up>(0)));
235 using swap2 =
decltype((test_swap<Up, Tp>(0)));
241 template <
class Tp,
class Up>
244 template <
class Tp,
class Up = Tp,
248 =
noexcept(
swap(std::declval<Tp>(), std::declval<Up>()))
249 and
noexcept(
swap(std::declval<Up>(), std::declval<Tp>()));
252 template <
class Tp,
class Up>
259 :
public std::integral_constant<bool,
260 detail::swappable_with<Tp&>::value> {};
264 :
public std::integral_constant<
265 bool, detail::nothrow_swappable_with<Tp&>::value> {};
269 template <
class Tp,
class Up>
271 :
public std::integral_constant<bool,
272 detail::swappable_with<Tp, Up>::value> {
277 :
public std::conditional<
278 detail::is_referenceable<Tp>::value,
279 is_swappable_with<typename std::add_lvalue_reference<Tp>::type,
280 typename std::add_lvalue_reference<Tp>::type>,
281 std::false_type>::type {};
283 template <
class Tp,
class Up>
285 :
public integral_constant<
286 bool, detail::nothrow_swappable_with<Tp, Up>::value> {};
290 :
public conditional<
291 detail::is_referenceable<Tp>::value,
292 is_nothrow_swappable_with<typename add_lvalue_reference<Tp>::type,
293 typename add_lvalue_reference<Tp>::type>,
294 false_type>::type {};
296 template <
class Tp,
class Up>
302 template <
class Tp,
class Up>
312 template <
typename F>
315 : fd(
std::forward<F>(f)) {}
319 template <
class... Args>
321 Args&&... args) & ->
decltype(not std::
325 return not
invoke(fd, std::forward<Args>(args)...);
328 template <
class... Args>
331 std::decay_t<F>
const&, Args...>>()) {
332 return not
invoke(std::move(fd), std::forward<Args>(args)...);
339 template <
typename F>
349 template <
class ForwardIt>
350 constexpr auto max_element(ForwardIt first, ForwardIt last) -> ForwardIt {
355 ForwardIt largest = first;
357 for (; first != last; ++first) {
358 if (*largest < *first) {
365 template <
class ForwardIt,
class Compare>
367 Compare comp) -> ForwardIt {
372 ForwardIt largest = first;
374 for (; first != last; ++first) {
375 if (comp(*largest, *first)) {
383 constexpr auto size(
const C& c) ->
decltype(c.size()) {
387 template <
class T, std::
size_t N>
388 constexpr auto size(
const T (&)[N])
noexcept -> std::size_t {
396 template <
class Ret,
class Fp,
class... Args>
398 template <
class XFp,
class... XArgs>
401 std::declval<XArgs>()...));
402 template <
class XFp,
class... XArgs>
405 using Result =
decltype(try_call<Fp, Args...>(0));
407 using type =
typename std::conditional<
410 std::is_convertible<Result, Ret>>::type,
411 std::false_type>::type;
414 template <
class Fp,
class... Args>
417 template <
bool IsInvokable,
bool IsCVVoid,
class Ret,
class Fp,
423 template <
class Ret,
class Fp,
class... Args>
430 static const bool value =
noexcept(ThisT::test_noexcept<Ret>(
431 kblib::invoke(std::declval<Fp>(), std::declval<Args>()...)));
434 template <
class Ret,
class Fp,
class... Args>
440 template <
class Ret,
class Fp,
class... Args>
445 template <
class Fp,
class... Args>
450 template <
class Fp,
class... Args>
452 :
public std::enable_if<
453 invokable<Fp, Args...>::value,
454 typename invokable_r<void, Fp, Args...>::Result> {};
459 template <
class Fn,
class... Args>
461 : std::integral_constant<bool, detail::invokable<Fn, Args...>::value> {};
463 template <
class Ret,
class Fn,
class... Args>
465 : std::integral_constant<bool,
466 detail::invokable_r<Ret, Fn, Args...>::value> {
469 template <
class Fn,
class... Args>
472 template <
class Ret,
class Fn,
class... Args>
477 template <
class Fn,
class... Args>
479 : std::integral_constant<bool,
480 detail::nothrow_invokable<Fn, Args...>::value> {
483 template <
class Ret,
class Fn,
class... Args>
485 : std::integral_constant<
486 bool, detail::nothrow_invokable_r<Ret, Fn, Args...>::value> {};
488 template <
class Fn,
class... Args>
492 template <
class Ret,
class Fn,
class... Args>
498namespace fakestd =
std;
513template <
typename... Ts>
521template <
typename... Ts>
536template <
typename T,
typename =
void>
542template <
typename... T>
553template <
bool V,
typename T>
559template <
bool V,
typename T>
564 template <
typename F,
typename Arg,
typename =
void>
566 template <std::size_t... Is>
567 constexpr static auto do_apply(F&& f, Arg&& arg)
noexcept(
569 std::get<Is>(std::forward<Arg>(arg))...)))
572 std::get<Is>(std::forward<Arg>(arg))...);
578template <
typename F,
typename Arg>
579constexpr auto apply(F&& f, Arg&& arg)
noexcept(
581 std::forward<F>(f), std::forward<Arg>(arg),
584 return detail::apply_impl<F, Arg>::do_apply(
585 std::forward<F>(f), std::forward<Arg>(arg),
591 return std::unique_ptr<T>(p);
593template <
typename T,
typename D>
595 return std::unique_ptr<T, D>(p, d);
603 return static_cast<std::make_unsigned_t<I>
>(x);
610 return static_cast<std::make_signed_t<I>
>(x);
617template <
typename A,
typename F>
621 std::make_signed_t<F>> {
629template <
typename A,
typename F>
633 std::make_unsigned_t<F>> {
640 using yes = char (&)[1];
641 using no = char (&)[2];
643 template <
typename C>
644 static auto check(
decltype(&
C::swap)) -> yes;
646 static auto check(...) -> no;
649 constexpr static bool value =
sizeof(check<T>(
nullptr)) ==
sizeof(yes);
652template <
typename T,
typename =
void>
661 template <
typename... Ts>
662 constexpr auto ignore(Ts&&... ) noexcept ->
void {}
666 template <
typename T, std::size_t... Is>
669 noexcept(
ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)),
671 ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)), 0)...);
689 auto tmp = std::move(
a);
702 noexcept(
noexcept(
a.swap(b))) ->
void {
712 template <
typename T, std::
size_t N>
713 KBLIB_UNUSED constexpr auto operator()(T (&
a)[N], T (&b)[N])
const
716 for (std::size_t i = 0; i < N; ++i) {
731 KBLIB_UNUSED constexpr auto operator()(T&
a, T& b)
const noexcept(
noexcept(
737template <
typename T,
typename U = T>
739 T old_value = std::move(obj);
740 obj = std::forward<U>(new_value);
748 template <
typename T>
758 return (x & ~(x >> 1u));
761 template <
typename Num>
763 return static_cast<Num
>(
typename std::make_unsigned<Num>::type{1}
764 << (std::numeric_limits<Num>::digits - 1u));
767 template <
class... Args>
769 template <std::
size_t N>
770 using type =
typename std::tuple_element<N, std::tuple<Args...>>::type;
773 template <auto K,
typename V>
775 constexpr static auto key = K;
779 template <
typename Key,
typename Comp,
typename... Vals>
782 template <std::
size_t I>
783 using element =
typename types::template type<I>;
785 template <Key key, std::
size_t I = 0>
787 static_assert(I <
sizeof...(Vals),
"key not found");
791 return get<key, I + 1>();
795 template <Key key,
typename Default =
void, std::
size_t I = 0>
797 if constexpr (I ==
sizeof...(Vals)) {
802 return get<key, I + 1>();
807 template <
typename N>
811 template <
typename T>
813 static_assert(max_val<T> < max_val<std::intmax_t>,
814 "Cannot safely promote intmax_t.");
816 template <
typename U>
828 typename decltype(ints_map::template get_default<max_val<T>
835 template <
typename N>
840 template <
typename N>
846 template <
typename N>
851 template <
typename N>
856template <
typename N,
typename =
void>
861 using type = std::conditional_t<
877template <
typename C,
typename T,
878 bool = std::is_const<typename std::remove_reference<C>::type>
::value>
881template <
typename C,
typename T>
884template <
typename C,
typename T>
887template <
typename C,
typename T>
890template <
typename C,
typename V>
893template <
typename T,
typename =
void>
898 using type =
typename T::value_type;
906template <
typename T,
typename =
void>
911 using type =
typename T::key_type;
919template <
typename T,
typename =
void>
924 using type =
typename T::mapped_type;
932template <
typename T,
typename =
void>
937 using type =
typename T::hasher;
945template <
typename Container,
bool = key_detected_v<Container>,
946 typename T =
typename Container::value_type>
949template <
typename Container>
951 :
meta_type<typename Container::value_type> {};
953template <
typename Container>
956template <
typename Container>
957constexpr static bool is_linear_container_v
958 = value_detected_v<Container> and not key_detected_v<Container>;
960template <
typename Container>
963template <
typename Container,
bool = key_detected_v<Container>,
964 bool = mapped_detected_v<Container>>
967template <
typename Container>
969 :
meta_type<typename Container::key_type> {};
971template <
typename Container>
974template <
typename Container>
975constexpr static bool is_setlike_v
976 = (key_detected_v<Container> and value_detected_v<Container>
977 and not mapped_detected_v<Container>
978 and std::is_same<key_detected_t<Container>,
981template <
class InputIt1,
class InputIt2>
983 InputIt2 first2) ->
bool {
984 for (; first1 != last1; ++first1, ++first2) {
985 if (not (*first1 == *first2)) {
992template <
typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
998 BinaryPredicate p) ->
bool {
999 for (; first1 != last1; ++first1, ++first2) {
1000 if (not p(*first1, *first2)) {
1006template <
class RandomIt1,
class RandomIt2,
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,
1018 RandomIt2 last2) ->
bool {
1019 if (std::distance(first1, last1) == std::distance(first2, last2)) {
1022 for (; first1 != last1; ++first1, ++first2) {
1023 if (not (*first1 == *first2)) {
1030template <
class RandomIt1,
class RandomIt2,
typename BinaryPredicate,
1032 std::is_base_of<std::random_access_iterator_tag,
1033 typename std::iterator_traits<
1034 RandomIt1>::iterator_category>
::value
1035 and std::is_base_of<std::random_access_iterator_tag,
1036 typename std::iterator_traits<
1037 RandomIt2>::iterator_category>
::value,
1041 RandomIt2 first2, RandomIt2 last2,
1042 BinaryPredicate p) ->
bool {
1043 if (std::distance(first1, last1) == std::distance(first2, last2)) {
1046 for (; first1 != last1; ++first1, ++first2) {
1047 if (not p(*first1, *first2)) {
1054 class InputIt1,
class InputIt2,
1056 not std::is_base_of<
1057 std::random_access_iterator_tag,
1058 typename std::iterator_traits<InputIt1>::iterator_category>
::value
1059 or not std::is_base_of<std::random_access_iterator_tag,
1060 typename std::iterator_traits<
1061 InputIt2>::iterator_category>
::value,
1065 InputIt2 first2, InputIt2 last2) ->
bool {
1066 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1067 if (not (*first1 == *first2)) {
1071 return (first1 == last1 and first2 == last2);
1075 typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
1077 not std::is_base_of<
1078 std::random_access_iterator_tag,
1079 typename std::iterator_traits<InputIt1>::iterator_category>
::value
1080 or not std::is_base_of<std::random_access_iterator_tag,
1081 typename std::iterator_traits<
1082 InputIt2>::iterator_category>
::value,
1086 InputIt2 first2, InputIt2 last2,
1087 BinaryPredicate p) ->
bool {
1088 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1089 if (not p(*first1, *first2)) {
1093 return (first1 == last1 and first2 == last2);
1096template <
typename C>
1101template <
typename T, std::
size_t N>
1106template <
class InputIt1,
class InputIt2>
1110 InputIt2 last2) ->
bool {
1111 for (; (first1 != last1) and (first2 != last2); ++first1, (void)++first2) {
1112 if (*first1 < *first2) {
1115 if (*first2 < *first1) {
1119 return (first1 == last1) and (first2 != last2);
1123 template <
typename D,
typename T,
typename =
void>
1128 template <
typename D,
typename T>
1138template <
typename T>
1152 template <
typename... Args,
1155 : p{new T(args...)} {}
1156 template <
typename... Args>
1158 : p{new T{args...}} {}
1161 : p{(u.p ? (new T(*u.p)) : nullptr)} {}
1173 p.reset(
new T(*u.p));
1190 p.
reset(
new T(val));
1196 p.
reset(
new T(std::move(val)));
1199 constexpr auto assign() & ->
void { p.reset(
new T()); }
1200 constexpr auto assign(
const T& val) & ->
void { p.reset(
new T(val)); }
1201 constexpr auto assign(T&& val) & ->
void { p.reset(
new T(std::move(val))); }
1202 template <
typename... Args,
1205 p.reset(
new T(std::forward<Args>(args)...));
1207 template <
typename... Args>
1209 p.reset(
new T{std::forward<Args>(args)...});
1212 constexpr auto reset() noexcept ->
void {
1218 return p !=
nullptr;
1264 std::unique_ptr<element_type> p;
1267template <
typename T,
typename D>
1269 using Base = std::unique_ptr<T, D>;
1272 using typename Base::deleter_type;
1273 using typename Base::element_type;
1274 using typename Base::pointer;
1279 using Base::operator=;
1283 using Base::release;
1288 using Base::get_deleter;
1289 using Base::operator bool;
1291 using Base::operator*;
1292 using Base::operator->;
1304 -> const element_type&& {
1311template <
typename T,
typename D>
1313 using Base = std::unique_ptr<T[], D>;
1316 using typename Base::deleter_type;
1317 using typename Base::element_type;
1318 using typename Base::pointer;
1323 using Base::operator=;
1327 using Base::release;
1332 using Base::get_deleter;
1333 using Base::operator bool;
1335 using Base::operator[];
1347 -> const element_type&& {
constexpr auto value() const &&noexcept -> const element_type &&
constexpr auto value() &&noexcept -> element_type &&
heap_value2 & operator=(const heap_value2 &other)
heap_value2(const heap_value2 &other)
const element_type & const_reference
constexpr auto value() &noexcept -> reference
constexpr auto value() const &noexcept -> const_reference
constexpr auto value() &&noexcept -> element_type &&
heap_value2 & operator=(const heap_value2 &other)
constexpr auto value() &noexcept -> reference
heap_value2(const heap_value2 &other)
constexpr auto value() const &&noexcept -> const element_type &&
constexpr auto value() const &noexcept -> const_reference
decltype(*std::declval< pointer >()) reference
const element_type & const_reference
constexpr auto operator=(heap_value &&u) &noexcept -> heap_value &
constexpr auto operator*() &noexcept -> reference
constexpr auto value() &&noexcept -> T &&
constexpr auto operator*() const &&noexcept -> const T &&
constexpr auto operator->() const &noexcept -> const_pointer
constexpr auto operator=(const heap_value &u) &-> heap_value &
constexpr auto assign(T &&val) &-> void
constexpr heap_value(heap_value &&u) noexcept
constexpr heap_value() noexcept
constexpr heap_value(in_place_agg_t, Args &&... args)
constexpr auto swap(heap_value &other) noexcept -> void
constexpr auto assign(in_place_agg_t, Args &&... args) -> void
constexpr auto value() const &&noexcept -> const T &&
constexpr auto value() const &noexcept -> const_reference
constexpr heap_value(std::nullptr_t) noexcept
constexpr heap_value(fakestd::in_place_t, Args &&... args)
constexpr auto get() &noexcept -> pointer
constexpr auto get() const &noexcept -> const_pointer
constexpr auto operator->() &noexcept -> pointer
constexpr auto operator=(T &&val) &-> heap_value &
const T & const_reference
constexpr auto reset() noexcept -> void
constexpr auto assign(fakestd::in_place_t, Args &&... args) -> void
constexpr auto operator=(const T &val) &-> heap_value &
constexpr auto assign() &-> void
constexpr auto operator*() const &noexcept -> const_reference
constexpr auto operator*() &&noexcept -> T &&
constexpr heap_value(const heap_value &u)
constexpr auto assign(const T &val) &-> void
constexpr auto value() &noexcept -> reference
GeneratorWrapper< T > value(T &&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(Member mem, Pointer ptr) noexcept -> 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 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 auto max_element(ForwardIt first, ForwardIt last, Compare comp) -> ForwardIt
constexpr bool is_invocable_r_v
constexpr bool is_nothrow_invocable_r_v
constexpr struct kblib::nums::max_t max
typename key_type_setlike< Container >::type key_type_setlike_t
constexpr auto size(const T(&)[N]) noexcept -> std::size_t
constexpr auto exchange(T &obj, U &&new_value) -> T
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 equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p) -> bool
auto to_unique(owner< T * > p, D &&d) -> std::unique_ptr< T, D >
constexpr auto signed_promote(N x) noexcept -> safe_signed_t< N >
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.
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 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)
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.