template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
template<typename T>
struct has_iterator {
template<typename U>
static auto test(int) -> decltype(std::begin(std::declval<U&>()), std::end(std::declval<U&>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
constexpr bool has_iterator_v = has_iterator<T>::value;
template<typename T>
struct has_size {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().size(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<has_iterator_v<std::decay_t<T>>, void> {
for (auto&& elem : t) { serialize(elem); }
}
template<typename T>
auto serialize(T&& t) -> std::enable_if_t<!has_iterator_v<std::decay_t<T>>, void> {
write(std::forward<T>(t));
}
template<typename T>
struct is_callable {
template<typename U>
static auto test(int) -> decltype(std::declval<U>()(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<is_callable<F>::value, decltype(f())> {
return std::forward<F>(f)();
}
template<typename F, typename... Args>
auto invoke_if_callable(F&& f, Args&&... args) -> std::enable_if_t<!is_callable<F>::value, void> {
std::forward<F>(f)(std::forward<Args>(args)...);
}
template<typename T>
struct has_value_type {
template<typename U>
static auto test(int) -> decltype(typename U::value_type{}, std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto get_first(Container&& c) -> std::enable_if_t<has_iterator_v<Container>, decltype(*std::begin(c))> {
return *std::begin(c);
}
template<typename T>
struct is_container {
static constexpr bool value = has_iterator_v<T> && has_size_v<T>;
};
template<typename T>
using enable_if_container = std::enable_if_t<is_container<T>::value, int>;
template<typename T>
struct has_push_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().push_back(std::declval<typename U::value_type>()), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
struct has_emplace_back {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().emplace_back(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_emplace_back<Container>::value, void> {
c.emplace_back(std::forward<Value>(v));
}
template<typename Container, typename Value>
auto add_element(Container& c, Value&& v) -> std::enable_if_t<has_push_back<Container>::value && !has_emplace_back<Container>::value, void> {
c.push_back(std::forward<Value>(v));
}
template<typename T>
struct is_arithmetic {
static constexpr bool value = std::is_arithmetic_v<T>;
};
template<typename T>
struct has_operator_plus {
template<typename U>
static auto test(int) -> decltype(std::declval<U>() + std::declval<U>(), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename T>
auto add(T&& a, T&& b) -> std::enable_if_t<has_operator_plus<std::decay_t<T>>::value, decltype(a + b)> {
return std::forward<T>(a) + std::forward<T>(b);
}
template<typename T>
struct has_reserve {
template<typename U>
static auto test(int) -> decltype(std::declval<U>().reserve(0), std::true_type{});
template<typename>
static std::false_type test(...);
using type = decltype(test<T>(0));
static constexpr bool value = type::value;
};
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<has_reserve<Container>::value, void> {
c.reserve(n);
}
template<typename Container>
auto optimize_capacity(Container& c, size_t n) -> std::enable_if_t<!has_reserve<Container>::value, void> {}
template<typename...> using void_t = void;
template<typename T, typename = void>
struct is_iterable : std::false_type {};
template<typename T>
struct is_iterable<T, void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>> : std::true_type {};
template<typename T>
constexpr bool is_iterable_v = is_iterable<T>::value;
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<is_iterable_v<T>, void> {
for (const auto& item : t) { process(item); }
}
template<typename T>
auto process_iterable(T&& t) -> std::enable_if_t<!is_iterable_v<T>, void> {
process_single(std::forward<T>(t));
}
Substitution Failure Is Not An Error