std::bind
"\x08\x0e\x0f\xae\x0b\xaf\x0b\xda\xf9\xfc\xd6\x0c\x82\x02\x00\x07" \
"\x00\x04\x0a\x90\x02\xb0\x0a\x02\x03\x04\x04\x90\x04\xb0\x06\x02" \
"\x02\x04\x02\xb0\x01\xb0\x04\x01\x00\x04\x01\xb0\x01\xb0\x03\x01" \
"\x00\x06\x00\x00\x00\x00\x00\x14\x00\x00\x01\x0b\x00\xcc\xcc\x80" \
"\xd1\x03\xcd\xf8\x88\x81\x02\xff\xfd\xfb\x87\x02\xff\xff\xfb\xf7" \
"\x0f\xff\xfd\xfb\xf7\x0f\xff\xfd\xfb\xf7\x0f\xff\xff\xfb\xf7\x0f" \
"\x8c\x01\xd2\xc8\xf0\xc1\x03\xff\xfd\xfb\x87\x02\xff\xfd\xfb\xf7" \
"\x0f\xff\xfd\xfb\xf7\x0f\xff\xfd\xfb\xf7\x0f\xff\xff\xfb\xf7\x0f" \
"\x00\x86\xe3\xd3\x0b\xa0\xfc\x80\x01\x0a\x00\x01\x00\x00\x00\x00"
new
and no casts. Here we have malloc()
=> it is C (or a fishy legacy C++).mod Main {
pub fn main() -> i32 {
let b: i32 = factorial(4);
return b;
}
pub fn factorial(n: i32) -> i32 {
if n == 1 {
return n;
} else {
return n * factorial(n - 1);
}
}
}
define i32 @main() local_unnamed_addr #1 !dbg !19 {
entry:
call void @llvm.dbg.value(metadata i32 24, metadata !23, metadata !DIExpression()), !dbg !25
call void @llvm.dbg.value(metadata i32 24, metadata !23, metadata !DIExpression()), !dbg !26
ret i32 24, !dbg !27
}
CHttp
. Otherwise, CChooseMaster
may wait forever for HTTP requests to be completed while the client is shutting down, if CHttp
was shutdown while CChooseMaster
is not waiting for an existing HTTP request.
Not directly caused by #7962, but it made it more likely to happen.
Closes #7980.
std::bind
just for this usecase, it just to avoid typing the out type of the vulkan functionstemplate<class Truth, class T, typename... Args>
struct conditional_impl {
using type = typename std::enable_if_t<(sizeof...(Args) == 0 && std::is_same_v<Truth, qpl::default_type>) || qpl::is_truth_type<Truth>(),
std::conditional_t<(sizeof...(Args) >= 2), std::conditional_t<qpl::is_true<Truth>(), std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, qpl::conditional_indirection<Args...>>,
std::conditional_t<(sizeof...(Args) == 0), std::conditional_t<std::is_same_v<Truth, qpl::default_type>, std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, std::enable_if<qpl::is_true<Truth>(), T>>,
std::conditional_t<qpl::is_true<Truth>(), std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, qpl::empty_indirection<Args...>>>>>::type;
};
it basically unrolls nested std::conditional_t's
so instead of writing
template<std::size_t N>
using unsigned_type = typename
std::conditional_t < N == std::size_t{ 8 }, std::type_identity<std::uint8_t>,
std::conditional_t < N == std::size_t{ 16 }, std::type_identity<std::uint16_t>,
std::conditional_t < N == std::size_t{ 32 }, std::type_identity<std::uint32_t>,
std::enable_if < N == std::size_t{ 64 }, std::uint64_t>>>>::type;
I can write
template<typename T>
using unsigned_type = qpl::conditional<
qpl::if_true<qpl::is_arithmetic<std::decay_t<T>>()>,
qpl::conditional<
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 8 }>, qpl::u8,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 16 }>, qpl::u16,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 32 }>, qpl::u32,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 64 }>, qpl::u64,
qpl::default_error>,
qpl::default_error>;
(not the lack of >>>> closing templates)
xDconstexpr for (int i = 0; i < 5; ++i)
with this function
#include <utility>
#include <type_traits>
template<size_t Size, typename F>
constexpr void constexpr_for(F&& function) {
auto unfold = [&]<size_t... Ints>(std::index_sequence<Ints...>) {
(std::forward<F>(function)(std::integral_constant<size_t, Ints>{}), ...);
};
unfold(std::make_index_sequence<Size>());
}
you can iterate over tuples very easily
auto tuple = std::make_tuple(0ull, 1, 2.0, "3", '4');
constexpr size_t size = std::tuple_size_v<decltype(tuple)>;
constexpr_for<size>([&](auto i) {
std::cout << std::get<i>(tuple) << ' ';
});
//prints 0 1 2 3 4
I use this for most of my constexpr template functions, it's a major life improvement for metemplate<class Truth, class T, typename... Args>
struct conditional_impl {
using type = typename std::enable_if_t<(sizeof...(Args) == 0 && std::is_same_v<Truth, qpl::default_type>) || qpl::is_truth_type<Truth>(),
std::conditional_t<(sizeof...(Args) >= 2), std::conditional_t<qpl::is_true<Truth>(), std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, qpl::conditional_indirection<Args...>>,
std::conditional_t<(sizeof...(Args) == 0), std::conditional_t<std::is_same_v<Truth, qpl::default_type>, std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, std::enable_if<qpl::is_true<Truth>(), T>>,
std::conditional_t<qpl::is_true<Truth>(), std::conditional_t<std::is_same_v<T, qpl::error_type>, T, qpl::identity<T>>, qpl::empty_indirection<Args...>>>>>::type;
};
it basically unrolls nested std::conditional_t's
so instead of writing
template<std::size_t N>
using unsigned_type = typename
std::conditional_t < N == std::size_t{ 8 }, std::type_identity<std::uint8_t>,
std::conditional_t < N == std::size_t{ 16 }, std::type_identity<std::uint16_t>,
std::conditional_t < N == std::size_t{ 32 }, std::type_identity<std::uint32_t>,
std::enable_if < N == std::size_t{ 64 }, std::uint64_t>>>>::type;
I can write
template<typename T>
using unsigned_type = qpl::conditional<
qpl::if_true<qpl::is_arithmetic<std::decay_t<T>>()>,
qpl::conditional<
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 8 }>, qpl::u8,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 16 }>, qpl::u16,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 32 }>, qpl::u32,
qpl::if_true<qpl::bits_in_type<T>() == std::size_t{ 64 }>, qpl::u64,
qpl::default_error>,
qpl::default_error>;
(not the lack of >>>> closing templates)
xD constexpr for (int i = 0; i < 5; ++i)
with this function
#include <utility>
#include <type_traits>
template<size_t Size, typename F>
constexpr void constexpr_for(F&& function) {
auto unfold = [&]<size_t... Ints>(std::index_sequence<Ints...>) {
(std::forward<F>(function)(std::integral_constant<size_t, Ints>{}), ...);
};
unfold(std::make_index_sequence<Size>());
}
you can iterate over tuples very easily
auto tuple = std::make_tuple(0ull, 1, 2.0, "3", '4');
constexpr size_t size = std::tuple_size_v<decltype(tuple)>;
constexpr_for<size>([&](auto i) {
std::cout << std::get<i>(tuple) << ' ';
});
//prints 0 1 2 3 4
I use this for most of my constexpr template functions, it's a major life improvement for me unordered_map
is stuck as a closed adressing hashmap