init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
146
Telegram/lib_rpl/rpl/details/callable.h
Normal file
146
Telegram/lib_rpl/rpl/details/callable.h
Normal file
@@ -0,0 +1,146 @@
|
||||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "base/build_config.h"
|
||||
#include <tuple>
|
||||
|
||||
namespace rpl {
|
||||
namespace details {
|
||||
|
||||
template <typename Arg>
|
||||
const Arg &const_ref_val() noexcept;
|
||||
|
||||
template <typename Arg>
|
||||
Arg &lvalue_ref_val() noexcept;
|
||||
|
||||
using false_t = char;
|
||||
struct true_t {
|
||||
false_t data[2];
|
||||
};
|
||||
static_assert(sizeof(false_t) != sizeof(true_t), "I can't work :(");
|
||||
|
||||
template <
|
||||
typename Method,
|
||||
typename ...Args,
|
||||
typename = decltype(std::invoke(
|
||||
std::declval<Method>(),
|
||||
std::declval<Args>()...))>
|
||||
true_t test_callable_plain(Method &&, Args &&...) noexcept;
|
||||
false_t test_callable_plain(...) noexcept;
|
||||
|
||||
template <typename Method, typename ...Args>
|
||||
struct is_callable_plain
|
||||
: std::bool_constant<(
|
||||
sizeof(test_callable_plain(
|
||||
std::declval<Method>(),
|
||||
std::declval<Args>()...
|
||||
)) == sizeof(true_t))> {
|
||||
};
|
||||
|
||||
template <typename Method, typename ...Args>
|
||||
constexpr bool is_callable_plain_v = is_callable_plain<Method, Args...>::value;
|
||||
|
||||
template <
|
||||
typename Method,
|
||||
typename ...Types,
|
||||
typename = decltype(std::declval<Method>()(
|
||||
std::declval<Types>()...))>
|
||||
true_t test_callable_tuple(
|
||||
Method &&,
|
||||
std::tuple<Types...> &&) noexcept;
|
||||
template <
|
||||
typename Method,
|
||||
typename ...Types,
|
||||
typename = decltype(std::declval<Method>()(
|
||||
const_ref_val<Types>()...))>
|
||||
true_t test_callable_tuple(
|
||||
Method &&,
|
||||
const std::tuple<Types...> &) noexcept;
|
||||
false_t test_callable_tuple(...) noexcept;
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
constexpr bool is_callable_tuple_v = (sizeof(test_callable_tuple(
|
||||
std::declval<Method>(),
|
||||
std::declval<Arg>())) == sizeof(true_t));
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
struct is_callable_tuple
|
||||
: std::bool_constant<
|
||||
is_callable_tuple_v<Method, Arg>> {
|
||||
};
|
||||
|
||||
template <typename Method, typename ...Args>
|
||||
struct is_callable;
|
||||
|
||||
template <typename Method>
|
||||
struct is_callable<Method>
|
||||
: std::bool_constant<
|
||||
is_callable_plain_v<Method>> {
|
||||
};
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
struct is_callable<Method, Arg>
|
||||
: std::bool_constant<
|
||||
is_callable_plain_v<Method, Arg> ||
|
||||
is_callable_tuple_v<Method, Arg> ||
|
||||
is_callable_plain_v<Method>> {
|
||||
};
|
||||
|
||||
template <typename Method, typename ...Args>
|
||||
constexpr bool is_callable_v = is_callable<Method, Args...>::value;
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
inline decltype(auto) callable_invoke(Method &&method, Arg &&arg) {
|
||||
if constexpr (is_callable_plain_v<Method, Arg>) {
|
||||
return std::invoke(std::forward<Method>(method), std::forward<Arg>(arg));
|
||||
} else if constexpr (is_callable_tuple_v<Method, Arg>) {
|
||||
return std::apply(
|
||||
std::forward<Method>(method),
|
||||
std::forward<Arg>(arg));
|
||||
} else if constexpr (is_callable_v<Method>) {
|
||||
return std::forward<Method>(method)();
|
||||
} else {
|
||||
static_assert(false_(method, arg), "Bad callable_invoke() call.");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
using callable_result = decltype(callable_invoke(
|
||||
std::declval<Method>(),
|
||||
std::declval<Arg>()));
|
||||
|
||||
template <
|
||||
typename Method,
|
||||
typename Arg,
|
||||
typename = decltype(std::invoke(
|
||||
std::declval<Method>(),
|
||||
const_ref_val<std::decay_t<Arg>>()))>
|
||||
true_t test_allows_const_ref(Method &&, Arg &&) noexcept;
|
||||
false_t test_allows_const_ref(...) noexcept;
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
constexpr bool allows_const_ref_v = (sizeof(test_allows_const_ref(
|
||||
std::declval<Method>(),
|
||||
std::declval<Arg>())) == sizeof(true_t));
|
||||
|
||||
template <typename Method, typename Arg>
|
||||
inline decltype(auto) const_ref_call_invoke(
|
||||
Method &&method,
|
||||
const Arg &arg) {
|
||||
if constexpr (allows_const_ref_v<Method, Arg>) {
|
||||
return callable_invoke(std::forward<Method>(method), arg);
|
||||
} else {
|
||||
auto copy = arg;
|
||||
return callable_invoke(
|
||||
std::forward<Method>(method),
|
||||
std::move(copy));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace rpl
|
||||
22
Telegram/lib_rpl/rpl/details/superset_type.h
Normal file
22
Telegram/lib_rpl/rpl/details/superset_type.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#pragma once
|
||||
|
||||
namespace rpl {
|
||||
|
||||
template <typename Value1, typename Value2>
|
||||
struct superset_type;
|
||||
|
||||
template <typename Value1, typename Value2>
|
||||
using superset_type_t = typename superset_type<Value1, Value2>::type;
|
||||
|
||||
template <typename Value>
|
||||
struct superset_type<Value, Value> {
|
||||
using type = Value;
|
||||
};
|
||||
|
||||
} // namespace rpl
|
||||
179
Telegram/lib_rpl/rpl/details/type_list.h
Normal file
179
Telegram/lib_rpl/rpl/details/type_list.h
Normal file
@@ -0,0 +1,179 @@
|
||||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rpl {
|
||||
namespace details {
|
||||
namespace type_list {
|
||||
|
||||
template <typename ...Types>
|
||||
struct list {
|
||||
};
|
||||
|
||||
template <typename Type, typename ...Types>
|
||||
struct list<Type, Types...> {
|
||||
using head = Type;
|
||||
using tail = list<Types...>;
|
||||
};
|
||||
|
||||
using empty_list = list<>;
|
||||
|
||||
template <typename TypeList>
|
||||
using head_t = typename TypeList::head;
|
||||
|
||||
template <typename TypeList>
|
||||
using tail_t = typename TypeList::tail;
|
||||
|
||||
template <typename Head, typename Tail>
|
||||
struct construct;
|
||||
|
||||
template <typename Head, typename Tail>
|
||||
using construct_t = typename construct<Head, Tail>::type;
|
||||
|
||||
template <typename Head, typename ...Types>
|
||||
struct construct<Head, list<Types...>> {
|
||||
using type = list<Head, Types...>;
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
struct size;
|
||||
|
||||
template <typename TypeList>
|
||||
constexpr std::size_t size_v = size<TypeList>::value;
|
||||
|
||||
template <typename ...Types>
|
||||
struct size<list<Types...>>
|
||||
: std::integral_constant<
|
||||
std::size_t,
|
||||
sizeof...(Types)> {
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
constexpr bool empty_v = (size_v<TypeList> == 0);
|
||||
|
||||
template <typename TypeList>
|
||||
struct empty : std::bool_constant<empty_v<TypeList>> {
|
||||
};
|
||||
|
||||
template <std::size_t Index, typename TypeList>
|
||||
struct get;
|
||||
|
||||
template <std::size_t Index, typename TypeList>
|
||||
using get_t = typename get<Index, TypeList>::type;
|
||||
|
||||
template <std::size_t Index, typename TypeList>
|
||||
struct get {
|
||||
using type = get_t<Index - 1, tail_t<TypeList>>;
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
struct get<0, TypeList> {
|
||||
using type = head_t<TypeList>;
|
||||
};
|
||||
|
||||
template <typename TypeList1, typename TypeList2>
|
||||
struct concat;
|
||||
|
||||
template <typename TypeList1, typename TypeList2>
|
||||
using concat_t = typename concat<TypeList1, TypeList2>::type;
|
||||
|
||||
template <typename ...Types1, typename ...Types2>
|
||||
struct concat<list<Types1...>, list<Types2...>> {
|
||||
using type = list<Types1..., Types2...>;
|
||||
};
|
||||
|
||||
template <typename TypeList, typename Type>
|
||||
struct remove_all;
|
||||
|
||||
template <typename TypeList, typename Type>
|
||||
using remove_all_t = typename remove_all<TypeList, Type>::type;
|
||||
|
||||
template <typename TypeList, typename Type>
|
||||
struct remove_all {
|
||||
using head = head_t<TypeList>;
|
||||
using tail = tail_t<TypeList>;
|
||||
using clean_tail = remove_all_t<tail, Type>;
|
||||
using type = std::conditional_t<
|
||||
std::is_same_v<head, Type>,
|
||||
clean_tail,
|
||||
construct_t<head, clean_tail>>;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct remove_all<empty_list, Type> {
|
||||
using type = empty_list;
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
struct last;
|
||||
|
||||
template <typename TypeList>
|
||||
using last_t = typename last<TypeList>::type;
|
||||
|
||||
template <typename TypeList>
|
||||
struct last {
|
||||
using type = last_t<tail_t<TypeList>>;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct last<list<Type>> {
|
||||
using type = Type;
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
struct chop_last;
|
||||
|
||||
template <typename TypeList>
|
||||
using chop_last_t = typename chop_last<TypeList>::type;
|
||||
|
||||
template <typename TypeList>
|
||||
struct chop_last {
|
||||
using type = construct_t<
|
||||
head_t<TypeList>,
|
||||
chop_last_t<tail_t<TypeList>>>;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct chop_last<list<Type>> {
|
||||
using type = empty_list;
|
||||
};
|
||||
|
||||
template <typename TypeList>
|
||||
struct distinct;
|
||||
|
||||
template <typename TypeList>
|
||||
using distinct_t = typename distinct<TypeList>::type;
|
||||
|
||||
template <typename TypeList>
|
||||
struct distinct {
|
||||
using type = construct_t<
|
||||
head_t<TypeList>,
|
||||
distinct_t<
|
||||
remove_all_t<tail_t<TypeList>, head_t<TypeList>>>>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct distinct<empty_list> {
|
||||
using type = empty_list;
|
||||
};
|
||||
|
||||
template <typename TypeList, template <typename ...> typename To>
|
||||
struct extract_to;
|
||||
|
||||
template <typename TypeList, template <typename ...> typename To>
|
||||
using extract_to_t = typename extract_to<TypeList, To>::type;
|
||||
|
||||
template <typename ...Types, template <typename ...> typename To>
|
||||
struct extract_to<list<Types...>, To> {
|
||||
using type = To<Types...>;
|
||||
};
|
||||
|
||||
} // namespace type_list
|
||||
} // namespace details
|
||||
} // namespace rpl
|
||||
Reference in New Issue
Block a user