NuriKit v0.1.0b2
Loading...
Searching...
No Matches
meta.h
Go to the documentation of this file.
1//
2// Project NuriKit - Copyright 2024 SNU Compbio Lab.
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#ifndef NURI_META_H_
7#define NURI_META_H_
8
10#include <iterator>
11#include <type_traits>
13
15
16#if defined(__clang_analyzer__) && __clang_major__ >= 18
17#define NURI_CLANG_ANALYZER_NOLINT [[clang::suppress]]
18#define NURI_CLANG_ANALYZER_NOLINT_BEGIN [[clang::suppress]] {
19#define NURI_CLANG_ANALYZER_NOLINT_END }
20#else
21#define NURI_CLANG_ANALYZER_NOLINT
22#define NURI_CLANG_ANALYZER_NOLINT_BEGIN
23#define NURI_CLANG_ANALYZER_NOLINT_END
24#endif
25
26namespace nuri {
27namespace internal {
28 // Use of std::underlying_type_t on non-enum types is UB until C++20.
29#if __cplusplus >= 202002L
30 using std::underlying_type;
31 using std::underlying_type_t;
32
33 using std::remove_cvref;
34 using std::remove_cvref_t;
35#else
36 template <class E, bool = std::is_enum_v<E>>
37 struct underlying_type { };
38
39 template <class E>
40 struct underlying_type<E, false> { };
41
42 template <class E>
43 struct underlying_type<E, true> {
44 using type = std::underlying_type_t<E>;
45 };
46
47 template <class T>
48 using underlying_type_t = typename underlying_type<T>::type;
49
50 template <class T>
51 struct remove_cvref {
52 using type = std::remove_cv_t<std::remove_reference_t<T>>;
53 };
54
55 template <class T>
56 using remove_cvref_t = typename remove_cvref<T>::type;
57#endif
58
59 template <class To, class From>
60 // NOLINTNEXTLINE(readability-identifier-naming)
61 constexpr inline bool is_implicitly_constructible_v =
62 std::is_constructible_v<To, From> && std::is_convertible_v<From, To>;
63
64 template <class To, class From>
65 // NOLINTNEXTLINE(readability-identifier-naming)
66 constexpr inline bool is_explicitly_constructible_v =
67 std::is_constructible_v<To, From> && !std::is_convertible_v<From, To>;
68
69 template <bool is_const, class T>
70 struct const_if {
71 using type = std::conditional_t<is_const, const T, T>;
72 };
73
74 template <bool is_const, class T>
75 using const_if_t = typename const_if<is_const, T>::type;
76
77 template <class Iterator, class T, class IfTrue = int>
78 using enable_if_compatible_iter_t =
79 std::enable_if_t<is_implicitly_constructible_v<
80 T, typename std::iterator_traits<Iterator>::reference>,
81 IfTrue>;
82
83 template <class Iter, class IteratorTag, class IfTrue = int>
84 using enable_if_iter_category_t = std::enable_if_t<
85 std::is_same_v<typename std::iterator_traits<Iter>::iterator_category,
86 IteratorTag>,
87 IfTrue>;
88
89 template <class T, bool = std::is_enum_v<T>>
90 struct extract_if_enum { };
91
92 template <class T>
93 struct extract_if_enum<T, true> {
94 using type = std::underlying_type_t<T>;
95 };
96
97 template <class T>
98 struct extract_if_enum<T, false> {
99 using type = T;
100 };
101
102 template <class T>
103 using extract_if_enum_t = typename extract_if_enum<T>::type;
104
105 template <class T, std::enable_if_t<
106 std::is_enum_v<T> || std::is_arithmetic_v<T>, int> = 0>
107 constexpr auto extract_if_enum_v(T val) {
108 return static_cast<extract_if_enum_t<T>>(val);
109 }
110
150 template <class... Args>
151 struct overload_cast_impl {
152 template <class Return>
153 constexpr decltype(auto)
154 operator()(Return (*func)(Args...)) const noexcept {
155 return func;
156 }
157
158 template <typename Return, typename Class>
159 constexpr decltype(auto)
160 operator()(Return (Class::*pmf)(Args...),
161 std::false_type /* dispatch */ = {}) const noexcept {
162 return pmf;
163 }
164
165 template <typename Return, typename Class>
166 constexpr decltype(auto)
167 operator()(Return (Class::*pmf)(Args...) const,
168 std::true_type /* dispatch */) const noexcept {
169 return pmf;
170 }
171 };
172} // namespace internal
173
174template <class... Args>
175// NOLINTNEXTLINE(readability-identifier-naming)
176constexpr inline static internal::overload_cast_impl<Args...> overload_cast;
177} // namespace nuri
178
179#endif /* NURI_META_H_ */
Definition crdgen.h:16