packio
utils.h
1 // This Source Code Form is subject to the terms of the Mozilla Public
2 // License, v. 2.0. If a copy of the MPL was not distributed with this
3 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 
5 #ifndef PACKIO_UTILS_H
6 #define PACKIO_UTILS_H
7 
8 #include <sstream>
9 #include <string_view>
10 #include <type_traits>
11 #include <vector>
12 
13 #include "config.h"
14 #include "log.h"
15 
16 namespace packio {
17 namespace internal {
18 
19 template <typename, typename = void>
20 struct func_traits : std::false_type {
21 };
22 
23 template <typename T>
24 struct func_traits<T, std::void_t<decltype(&std::decay_t<T>::operator())>>
25  : func_traits<decltype(&std::decay_t<T>::operator())> {
26 };
27 
28 template <typename C, typename R, typename... Args>
29 struct func_traits<R (C::*)(Args...)> : func_traits<R (*)(Args...)> {
30 };
31 
32 template <typename C, typename R, typename... Args>
33 struct func_traits<R (C::*)(Args...) const> : func_traits<R (*)(Args...)> {
34 };
35 
36 template <typename R, typename... Args>
37 struct func_traits<R (*)(Args...)> : std::true_type {
38  using result_type = R;
39  using args_type = std::tuple<Args...>;
40  static constexpr auto args_count = std::tuple_size_v<args_type>;
41 };
42 
43 template <typename T>
44 constexpr bool func_traits_v = func_traits<T>::value;
45 
46 template <typename>
47 struct is_awaitable : std::false_type {
48 };
49 
50 #if defined(PACKIO_HAS_CO_AWAIT)
51 template <typename... Args>
52 struct is_awaitable<net::awaitable<Args...>> : std::true_type {
53 };
54 #endif // defined(PACKIO_HAS_CO_AWAIT)
55 
56 template <typename, typename = void>
57 struct is_coroutine : std::false_type {
58 };
59 
60 template <typename T>
61 struct is_coroutine<T, std::enable_if_t<func_traits_v<T>>>
62  : is_awaitable<typename func_traits<T>::result_type> {
63 };
64 
65 template <typename T>
66 constexpr bool is_coroutine_v = is_coroutine<T>::value;
67 
68 template <typename T, typename = void>
69 struct is_tuple : std::false_type {
70 };
71 
72 template <typename T>
73 struct is_tuple<T, std::void_t<decltype(std::tuple_size<std::decay_t<T>>::value)>>
74  : std::true_type {
75 };
76 
77 template <typename T>
78 constexpr auto is_tuple_v = is_tuple<T>::value;
79 
80 template <typename T>
81 struct left_shift_tuple;
82 
83 template <typename A, typename... Bs>
84 struct left_shift_tuple<std::tuple<A, Bs...>> {
85  using type = std::tuple<Bs...>;
86 };
87 
88 template <typename T>
89 using left_shift_tuple_t = typename left_shift_tuple<T>::type;
90 
91 template <template <typename...> class Map, typename T>
92 struct map_tuple;
93 
94 template <template <typename...> class Map, typename... Args>
95 struct map_tuple<Map, std::tuple<Args...>> {
96  using type = std::tuple<Map<Args>...>;
97 };
98 
99 template <template <typename...> class Map, typename T>
100 using map_tuple_t = typename map_tuple<Map, T>::type;
101 
102 template <typename T>
103 using decay_tuple_t = map_tuple_t<std::decay_t, T>;
104 
105 template <typename... Args>
106 struct always_false : std::false_type {
107 };
108 
109 template <typename... Args>
110 constexpr auto always_false_v = always_false<Args...>::value;
111 
112 template <typename T>
113 void set_no_delay(T&)
114 {
115 }
116 
117 template <>
118 inline void set_no_delay(net::ip::tcp::socket& socket)
119 {
120  error_code ec;
121  socket.set_option(net::ip::tcp::no_delay{true}, ec);
122  if (ec) {
123  PACKIO_WARN("error setting tcp nodelay option: {}", ec.message());
124  }
125 }
126 
127 template <typename T>
128 std::unique_ptr<std::decay_t<T>> to_unique_ptr(T&& value)
129 {
130  return std::make_unique<std::decay_t<T>>(std::forward<T>(value));
131 }
132 
133 template <typename Executor, typename Obj>
134 auto bind_executor(Executor&& executor, Obj&& obj)
135 {
136  return net::bind_executor(
137  any_io_executor(std::forward<Executor>(executor)),
138  std::forward<Obj>(obj));
139 }
140 
141 } // internal
142 } // packio
143 
144 #endif // PACKIO_UTILS_H
The packio namespace.
Definition: arg.h:14