32 #ifndef KBLIB_FAKESTD_H
33 #define KBLIB_FAKESTD_H
40 #include <type_traits>
43 #if __has_include("gsl/pointers")
44 # include "gsl/pointers"
48 # define KBLIB_FAKESTD (__cplusplus < 201703L)
53 template <
bool B,
typename T =
void>
57 using 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
72 template <
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)...));
85 typename F,
typename... Args,
86 enable_if_t<not std::is_member_pointer<decay_t<F>>::value,
int> = 0>
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((obj.*f)(std::forward<Args>(args)...))) -> decltype(
auto) {
98 return (obj.*f)(std::forward<Args>(args)...);
101 template <
typename F,
typename Pointer,
typename... Args,
103 and std::is_member_function_pointer<F>::value,
105 constexpr
auto do_invoke(F f, Pointer ptr, Args&&... args) noexcept(
106 noexcept((ptr->*f)(std::forward<Args>(args)...))) -> decltype(
auto) {
107 return (ptr->*f)(std::forward<Args>(args)...);
110 template <
typename Member,
typename Object,
112 and std::is_member_object_pointer<Member>::value,
114 constexpr
auto do_invoke(Member mem, Object&& obj) noexcept
116 return std::forward<Object>(obj).*mem;
119 template <
typename Member,
typename Pointer,
121 and std::is_member_object_pointer<Member>::value,
123 constexpr
auto do_invoke(Member mem, Pointer ptr) noexcept
129 template <
typename F,
typename... Args>
130 constexpr
auto invoke(F&& f, Args&&... args) noexcept(noexcept(
157 template <
typename AlwaysVoid,
typename,
typename...>
159 template <
typename F,
typename... Args>
161 std::declval<Args>()...))),
164 = decltype(
invoke(std::declval<F>(), std::declval<Args>()...));
167 template <
class F,
class... ArgTypes>
170 template <
typename F,
typename... ArgTypes>
173 template <
typename... Ts>
177 template <
typename... Ts>
204 : std::integral_constant<
206 not std::is_same<decltype(is_referenceable_impl::test<Tp>(0)),
209 template <
class Tp,
class Up = Tp,
211 = not std::is_void<Tp>::value and not std::is_void<Up>::value>
213 template <
class LHS,
class RHS>
214 static decltype(
swap(std::declval<LHS>(), std::declval<RHS>()))
216 template <class, class>
227 template <class Tp, class Up>
230 template <
class Tp,
class Up = Tp,
234 swap(std::declval<Tp>(),
235 std::declval<Up>()))and noexcept(
swap(
std::declval<Up>(),
236 std::declval<Tp>()));
239 template <class Tp, class Up>
246 :
public std::integral_constant<bool,
247 detail::swappable_with<Tp&>::value> {};
251 :
public std::integral_constant<
252 bool, detail::nothrow_swappable_with<Tp&>::value> {};
256 template <
class Tp,
class Up>
258 :
public std::integral_constant<bool,
259 detail::swappable_with<Tp, Up>::value> {
264 :
public std::conditional<
265 detail::is_referenceable<Tp>::value,
266 is_swappable_with<typename std::add_lvalue_reference<Tp>::type,
267 typename std::add_lvalue_reference<Tp>::type>,
268 std::false_type>::type {};
270 template <
class Tp,
class Up>
272 :
public integral_constant<
273 bool, detail::nothrow_swappable_with<Tp, Up>::value> {};
277 :
public conditional<
278 detail::is_referenceable<Tp>::value,
279 is_nothrow_swappable_with<typename add_lvalue_reference<Tp>::type,
280 typename add_lvalue_reference<Tp>::type>,
281 false_type>::type {};
283 template <
class Tp,
class Up>
289 template <
class Tp,
class Up>
299 template <
typename F>
302 : fd(
std::forward<F>(f)) {}
306 template <
class... Args>
309 return not
invoke(fd, std::forward<Args>(args)...);
312 template <
class... Args>
313 constexpr
auto operator()(Args&&... args)
const& -> decltype(
316 return not
invoke(std::move(fd), std::forward<Args>(args)...);
323 template <
typename F>
333 template <
class ForwardIt>
334 constexpr
auto max_element(ForwardIt first, ForwardIt last) -> ForwardIt {
338 ForwardIt largest = first;
340 for (; first != last; ++first) {
341 if (*largest < *first) {
348 template <
class ForwardIt,
class Compare>
349 constexpr
auto max_element(ForwardIt first, ForwardIt last, Compare comp)
354 ForwardIt largest = first;
356 for (; first != last; ++first) {
357 if (comp(*largest, *first)) {
365 constexpr
auto size(
const C& c) -> decltype(c.size()) {
369 template <
class T, std::
size_t N>
370 constexpr
auto size(
const T (&)[N]) noexcept -> std::size_t {
378 template <
class Ret,
class Fp,
class... Args>
380 template <
class XFp,
class... XArgs>
383 std::declval<XArgs>()...));
384 template <
class XFp,
class... XArgs>
387 using Result = decltype(try_call<Fp, Args...>(0));
389 using type =
typename std::conditional<
390 not std::is_same<Result, detail::nat>::value,
391 typename std::conditional<std::is_void<Ret>::value, std::true_type,
392 std::is_convertible<Result, Ret>>
::type,
394 static const bool value = type::value;
396 template <
class Fp,
class... Args>
399 template <
bool IsInvokable,
bool IsCVVoid,
class Ret,
class Fp,
405 template <
class Ret,
class Fp,
class... Args>
412 static const bool value = noexcept(ThisT::test_noexcept<Ret>(
413 kblib::invoke(std::declval<Fp>(), std::declval<Args>()...)));
416 template <
class Ret,
class Fp,
class... Args>
422 template <
class Ret,
class Fp,
class... Args>
425 std::is_void<Ret>::value, Ret, Fp, Args...>;
427 template <
class Fp,
class... Args>
432 template <
class Fp,
class... Args>
434 :
public std::enable_if<
435 invokable<Fp, Args...>::value,
436 typename invokable_r<void, Fp, Args...>::Result> {};
441 template <
class Fn,
class... Args>
443 : std::integral_constant<bool, detail::invokable<Fn, Args...>::value> {};
445 template <
class Ret,
class Fn,
class... Args>
447 : std::integral_constant<bool,
448 detail::invokable_r<Ret, Fn, Args...>::value> {
451 template <
class Fn,
class... Args>
454 template <
class Ret,
class Fn,
class... Args>
459 template <
class Fn,
class... Args>
461 : std::integral_constant<bool,
462 detail::nothrow_invokable<Fn, Args...>::value> {
465 template <
class Ret,
class Fn,
class... Args>
467 : std::integral_constant<
468 bool, detail::nothrow_invokable_r<Ret, Fn, Args...>::value> {};
470 template <
class Fn,
class... Args>
474 template <
class Ret,
class Fn,
class... Args>
480 namespace fakestd =
std;
495 template <
typename... Ts>
498 template <
typename T>
503 template <
typename... Ts>
518 template <
typename T,
typename =
void>
521 template <
typename T>
524 template <
typename... T>
527 template <
typename T>
529 = std::integral_constant<decltype(T::value), T::value>;
535 template <
bool V,
typename T>
538 template <
typename T>
541 template <
bool V,
typename T>
546 template <
typename F,
typename Arg,
typename =
void>
548 template <std::size_t... Is>
549 constexpr
static auto do_apply(F&& f, Arg&& arg) noexcept(
551 std::get<Is>(std::forward<Arg>(arg))...)))
554 std::get<Is>(std::forward<Arg>(arg))...);
560 template <
typename F,
typename Arg>
561 constexpr
auto apply(F&& f, Arg&& arg) noexcept(
563 std::forward<F>(f), std::forward<Arg>(arg),
564 std::index_sequence<std::tuple_size<Arg>::value>{})))
567 std::forward<F>(f), std::forward<Arg>(arg),
568 std::index_sequence<std::tuple_size<Arg>::value>{});
571 template <
typename T>
573 return std::unique_ptr<T>(p);
575 template <
typename T,
typename D>
577 -> std::unique_ptr<T, D> {
578 return std::unique_ptr<T, D>(p, d);
584 template <
typename I>
586 return static_cast<std::make_unsigned_t<I>
>(x);
591 template <
typename I>
593 return static_cast<std::make_signed_t<I>
>(x);
600 template <
typename A,
typename F>
603 and std::is_signed<A>::value,
604 std::make_signed_t<F>> {
612 template <
typename A,
typename F>
614 -> enable_if_t<std::is_integral<A>::value and std::is_integral<F>::value
615 and std::is_unsigned<A>::value,
616 std::make_unsigned_t<F>> {
620 template <
typename T>
623 using yes = char (&)[1];
624 using no = char (&)[2];
626 template <
typename C>
627 static auto check(decltype(&
C::swap)) -> yes;
629 static auto check(...) -> no;
632 constexpr
static bool value =
sizeof(check<T>(
nullptr)) ==
sizeof(yes);
635 template <
typename T,
typename =
void>
638 template <
typename T>
644 template <
typename... Ts>
645 constexpr
auto ignore(Ts&&... ) noexcept ->
void {}
647 template <
typename T, std::size_t... Is>
650 noexcept(
ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)), 0)...)))
652 ignore(((
void)
swap(std::get<Is>(
a), std::get<Is>(b)), 0)...);
663 template <typename T, enable_if_t<not has_member_swap<T>::value
664 and not is_tuple_like<T>::value,
667 noexcept(std::is_nothrow_move_constructible<T>::value and
668 std::is_nothrow_move_assignable<T>::value) ->
void {
669 auto tmp = std::move(
a);
680 template <typename T, enable_if_t<has_member_swap<T>::value,
int> = 0>
682 noexcept(noexcept(
a.swap(b))) ->
void {
692 template <
typename T, std::
size_t N>
693 KBLIB_UNUSED constexpr
auto operator()(T (&
a)[N], T (&b)[N])
const
694 noexcept(std::is_nothrow_move_constructible<T>::value and
695 std::is_nothrow_move_assignable<T>::value) ->
void {
696 for (std::size_t i = 0; i < N; ++i) {
706 template <typename T, enable_if_t<is_tuple_like<T>::value
710 = std::tuple_size<T>::value>
711 KBLIB_UNUSED constexpr
auto operator()(T&
a, T& b)
const noexcept(noexcept(
717 template <
typename T,
typename U = T>
719 T old_value = std::move(obj);
720 obj = std::forward<U>(new_value);
728 template <
typename T>
738 return (x & ~(x >> 1u));
741 template <
typename Num>
743 return static_cast<Num
>(
typename std::make_unsigned<Num>::type{1}
744 << (std::numeric_limits<Num>::digits - 1u));
747 template <
class... Args>
749 template <std::
size_t N>
750 using type =
typename std::tuple_element<N, std::tuple<Args...>>
::type;
753 template <auto K,
typename V>
755 constexpr
static auto key = K;
759 template <
typename Key,
typename Comp,
typename... Vals>
762 template <std::
size_t I>
763 using element =
typename types::template type<I>;
765 template <Key key, std::
size_t I = 0>
767 static_assert(I <
sizeof...(Vals),
"key not found");
771 return get<key, I + 1>();
775 template <Key key,
typename Default =
void, std::
size_t I = 0>
777 if constexpr (I ==
sizeof...(Vals)) {
782 return get<key, I + 1>();
787 template <
typename N>
791 template <
typename T>
793 static_assert(max_val<T> < max_val<std::intmax_t>,
794 "Cannot safely promote intmax_t.");
796 template <
typename U>
807 using type =
typename decltype(
808 ints_map::template get_default<max_val<T> + 1>())::
type;
811 template <typename N, bool = std::is_signed<N>::value>
814 template <
typename N>
819 template <
typename N>
822 template <typename N, bool = std::is_unsigned<N>::value>
825 template <
typename N>
830 template <
typename N>
835 template <
typename N,
typename =
void>
838 template <
typename N>
840 using type = std::conditional_t<
841 std::is_signed<N>::value, N,
845 template <
typename N>
848 template <
typename N>
856 template <
typename C,
typename T,
857 bool = std::is_const<typename std::remove_reference<C>::type>::value>
860 template <
typename C,
typename T>
863 template <
typename C,
typename T>
866 template <
typename C,
typename T>
869 template <
typename C,
typename V>
872 template <
typename T,
typename =
void>
875 template <
typename T>
877 using type =
typename T::value_type;
880 template <
typename T>
882 template <
typename T>
885 template <
typename T,
typename =
void>
888 template <
typename T>
890 using type =
typename T::key_type;
893 template <
typename T>
895 template <
typename T>
898 template <
typename T,
typename =
void>
901 template <
typename T>
903 using type =
typename T::mapped_type;
906 template <
typename T>
908 template <
typename T>
911 template <
typename T,
typename =
void>
914 template <
typename T>
916 using type =
typename T::hasher;
919 template <
typename T>
921 template <
typename T>
924 template <
typename Container,
bool = key_detected_v<Container>,
925 typename T =
typename Container::value_type>
928 template <
typename Container>
930 :
meta_type<typename Container::value_type> {};
932 template <
typename Container>
935 template <
typename Container>
936 constexpr
static bool is_linear_container_v
937 = value_detected_v<Container> and not key_detected_v<Container>;
939 template <
typename Container>
942 template <
typename Container,
bool = key_detected_v<Container>,
943 bool = mapped_detected_v<Container>>
946 template <
typename Container>
948 :
meta_type<typename Container::key_type> {};
950 template <
typename Container>
953 template <
typename Container>
954 constexpr
static bool is_setlike_v
956 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);
958 template <
class InputIt1,
class InputIt2>
960 InputIt2 first2) ->
bool {
961 for (; first1 != last1; ++first1, ++first2) {
962 if (not (*first1 == *first2)) {
969 template <
typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
971 not std::is_same<InputIt2, BinaryPredicate>::value,
int> = 0>
973 InputIt2 first2, BinaryPredicate p)
975 for (; first1 != last1; ++first1, ++first2) {
976 if (not p(*first1, *first2)) {
982 template <
class RandomIt1,
class RandomIt2,
984 std::is_base_of<std::random_access_iterator_tag,
985 typename std::iterator_traits<
986 RandomIt1>::iterator_category>::value
987 and std::is_base_of<std::random_access_iterator_tag,
988 typename std::iterator_traits<
989 RandomIt2>::iterator_category>::value,
992 RandomIt2 first2, RandomIt2 last2)
994 if (std::distance(first1, last1) == std::distance(first2, last2)) {
997 for (; first1 != last1; ++first1, ++first2) {
998 if (not (*first1 == *first2)) {
1005 template <
class RandomIt1,
class RandomIt2,
typename BinaryPredicate,
1007 std::is_base_of<std::random_access_iterator_tag,
1008 typename std::iterator_traits<
1009 RandomIt1>::iterator_category>::value
1010 and std::is_base_of<std::random_access_iterator_tag,
1011 typename std::iterator_traits<
1012 RandomIt2>::iterator_category>::value,
1015 RandomIt2 first2, RandomIt2 last2,
1016 BinaryPredicate p) ->
bool {
1017 if (std::distance(first1, last1) == std::distance(first2, last2)) {
1020 for (; first1 != last1; ++first1, ++first2) {
1021 if (not p(*first1, *first2)) {
1028 class InputIt1,
class InputIt2,
1030 not std::is_base_of<
1031 std::random_access_iterator_tag,
1032 typename std::iterator_traits<InputIt1>::iterator_category>::value
1033 or not std::is_base_of<std::random_access_iterator_tag,
1034 typename std::iterator_traits<
1035 InputIt2>::iterator_category>::value,
1038 InputIt2 first2, InputIt2 last2) ->
bool {
1039 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1040 if (not (*first1 == *first2)) {
1044 return (first1 == last1 and first2 == last2);
1048 typename InputIt1,
typename InputIt2,
typename BinaryPredicate,
1050 not std::is_base_of<
1051 std::random_access_iterator_tag,
1052 typename std::iterator_traits<InputIt1>::iterator_category>::value
1053 or not std::is_base_of<std::random_access_iterator_tag,
1054 typename std::iterator_traits<
1055 InputIt2>::iterator_category>::value,
1058 InputIt2 first2, InputIt2 last2,
1059 BinaryPredicate p) ->
bool {
1060 for (; first1 != last1 and first2 != last2; ++first1, ++first2) {
1061 if (not p(*first1, *first2)) {
1065 return (first1 == last1 and first2 == last2);
1068 template <
typename C>
1073 template <
typename T, std::
size_t N>
1078 template <
class InputIt1,
class InputIt2>
1082 InputIt2 last2) ->
bool {
1083 for (; (first1 != last1) and (first2 != last2); ++first1, (void)++first2) {
1084 if (*first1 < *first2)
1086 if (*first2 < *first1)
1089 return (first1 == last1) and (first2 != last2);
1093 template <
typename D,
typename T,
typename =
void>
1098 template <
typename D,
typename T>
1108 template <
typename T>
1122 template <
typename... Args,
1123 enable_if_t<std::is_constructible<T, Args...>::value> = 0>
1125 : p{new T(args...)} {}
1126 template <
typename... Args,
1127 enable_if_t<std::is_constructible<T, Args...>::value> = 0>
1129 : p{new T{args...}} {}
1132 : p{(u.p ? (new T(*u.p)) : nullptr)} {}
1144 p.reset(
new T(*u.p));
1161 p.
reset(
new T(val));
1167 p.
reset(
new T(std::move(val)));
1170 auto assign() & ->
void { p.reset(
new T()); }
1171 auto assign(
const T& val) & ->
void { p.reset(
new T(val)); }
1172 auto assign(T&& val) & ->
void { p.reset(
new T(std::move(val))); }
1173 template <
typename... Args>
1175 p.reset(
new T(std::forward<Args>(args)...));
1177 template <
typename... Args>
1179 p.reset(
new T{std::forward<Args>(args)...});
1188 return p !=
nullptr;
1222 std::unique_ptr<element_type> p;
1225 template <
typename T,
typename D>
1227 using Base = std::unique_ptr<T, D>;
1230 using typename Base::deleter_type;
1231 using typename Base::element_type;
1232 using typename Base::pointer;
1237 using Base::operator=;
1241 using Base::release;
1246 using Base::get_deleter;
1247 using Base::operator bool;
1249 using Base::operator*;
1250 using Base::operator->;
1264 template <
typename T,
typename D>
1266 using Base = std::unique_ptr<T[], D>;
1269 using typename Base::deleter_type;
1270 using typename Base::element_type;
1271 using typename Base::pointer;
1276 using Base::operator=;
1280 using Base::release;
1285 using Base::get_deleter;
1286 using Base::operator bool;
1288 using Base::operator[];
auto value() const &noexcept -> const_reference
heap_value2 & operator=(const heap_value2 &other)
auto value() &&noexcept -> element_type &&
auto value() &noexcept -> reference
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(const heap_value2 &other)
auto value() &noexcept -> reference
heap_value2 & operator=(const heap_value2 &other)
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 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)
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.
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
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
constexpr static 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
constexpr static auto get() noexcept -> auto
constexpr static auto get_default() 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 not_fn_t(F &&f)
constexpr auto operator()(Args &&... args) const &-> decltype(not std::declval< invoke_result_t< std::decay_t< F > const &, Args... >>())
constexpr not_fn_t(not_fn_t &&)=default
constexpr not_fn_t(const not_fn_t &)=default
constexpr auto operator()(Args &&... args) &-> decltype(not std::declval< invoke_result_t< std::decay_t< F > &, Args... >>())
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
constexpr static 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.