RapidFuzz
Loading...
Searching...
No Matches
type_traits.hpp
1/* SPDX-License-Identifier: MIT */
2/* Copyright © 2020 Max Bachmann */
3
4#pragma once
5#include <rapidfuzz/details/types.hpp>
6
7#include <iterator>
8#include <utility>
9
10namespace rapidfuzz {
11
12namespace detail {
13template <typename T>
14auto inner_type(T const*) -> T;
15
16template <typename T>
17auto inner_type(T const&) -> typename T::value_type;
18} // namespace detail
19
20template <typename T>
21using char_type = decltype(detail::inner_type(std::declval<T const&>()));
22
23/* backport of std::iter_value_t from C++20
24 * This does not cover the complete functionality, but should be enough for
25 * the use cases in this library
26 */
27template <typename T>
28using iter_value_t = typename std::iterator_traits<T>::value_type;
29
30// taken from
31// https://stackoverflow.com/questions/16893992/check-if-type-can-be-explicitly-converted
32template <typename From, typename To>
33struct is_explicitly_convertible {
34 template <typename T>
35 static void f(T);
36
37 template <typename F, typename T>
38 static constexpr auto test(int /*unused*/) -> decltype(f(static_cast<T>(std::declval<F>())), true)
39 {
40 return true;
41 }
42
43 template <typename F, typename T>
44 static constexpr auto test(...) -> bool
45 {
46 return false;
47 }
48
49 static bool const value = test<From, To>(0);
50};
51
52template <bool B, class T = void>
53using rf_enable_if_t = typename std::enable_if<B, T>::type;
54
55} // namespace rapidfuzz