libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
format_argument.hpp
1#pragma once
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6#include <string>
7#include <string_view>
8#include <type_traits>
9#include <utility>
10
11#include "format_protocol.hpp"
12
13namespace LibXR::Print::Detail::FormatArgument
14{
25template <typename T>
27{
28 using Decayed = std::remove_cvref_t<T>;
29 using Normalized =
30 typename std::conditional_t<std::is_enum_v<Decayed>, std::underlying_type<Decayed>,
31 std::type_identity<Decayed>>::type;
32
33 static constexpr bool is_signed_integer = std::is_integral_v<Normalized> &&
34 !std::is_same_v<Normalized, bool> &&
35 std::is_signed_v<Normalized>;
36 static constexpr bool is_unsigned_integer = std::is_integral_v<Normalized> &&
37 !std::is_same_v<Normalized, bool> &&
38 std::is_unsigned_v<Normalized>;
39 static constexpr bool is_default_signed_integer =
40 is_signed_integer && sizeof(Normalized) <= sizeof(int);
41 static constexpr bool is_default_unsigned_integer =
42 is_unsigned_integer && sizeof(Normalized) <= sizeof(unsigned int);
43 static constexpr bool is_char_array =
44 std::is_array_v<Decayed> &&
45 std::is_same_v<std::remove_cv_t<std::remove_extent_t<Decayed>>, char>;
46 static constexpr bool is_c_string = std::is_same_v<Decayed, const char*> ||
47 std::is_same_v<Decayed, char*> || is_char_array;
48 static constexpr bool is_string_like = is_c_string ||
49 std::is_same_v<Decayed, std::string_view> ||
50 std::is_same_v<Decayed, std::string>;
51 static constexpr bool is_pointer_like =
52 (std::is_pointer_v<Decayed> &&
53 !std::is_function_v<std::remove_pointer_t<Decayed>>) ||
54 std::is_same_v<Decayed, std::nullptr_t>;
55 static constexpr bool is_character_like = std::is_integral_v<Normalized>;
56 static constexpr bool is_float =
57 std::is_same_v<Decayed, float> || std::is_same_v<Decayed, double>;
58 static constexpr bool is_long_double = std::is_same_v<Decayed, long double>;
59
67 [[nodiscard]] static consteval bool MatchesRule(FormatArgumentRule rule)
68 {
69 if (rule == FormatArgumentRule::None)
70 {
71 return true;
72 }
73
74 switch (rule)
75 {
76 case FormatArgumentRule::SignedAny:
77 return is_default_signed_integer;
78 case FormatArgumentRule::SignedChar:
79 return std::is_same_v<Normalized, signed char>;
80 case FormatArgumentRule::SignedShort:
81 return std::is_same_v<Normalized, short>;
82 case FormatArgumentRule::SignedLong:
83 return std::is_same_v<Normalized, long>;
84 case FormatArgumentRule::SignedLongLong:
85 return std::is_same_v<Normalized, long long>;
86 case FormatArgumentRule::SignedIntMax:
87 return std::is_same_v<Normalized, intmax_t>;
88 case FormatArgumentRule::SignedSize:
89 return std::is_same_v<Normalized, std::make_signed_t<size_t>>;
90 case FormatArgumentRule::SignedPtrDiff:
91 return std::is_same_v<Normalized, ptrdiff_t>;
92 case FormatArgumentRule::UnsignedAny:
93 return is_default_unsigned_integer;
94 case FormatArgumentRule::UnsignedChar:
95 return std::is_same_v<Normalized, unsigned char>;
96 case FormatArgumentRule::UnsignedShort:
97 return std::is_same_v<Normalized, unsigned short>;
98 case FormatArgumentRule::UnsignedLong:
99 return std::is_same_v<Normalized, unsigned long>;
100 case FormatArgumentRule::UnsignedLongLong:
101 return std::is_same_v<Normalized, unsigned long long>;
102 case FormatArgumentRule::UnsignedIntMax:
103 return std::is_same_v<Normalized, uintmax_t>;
104 case FormatArgumentRule::UnsignedSize:
105 return std::is_same_v<Normalized, size_t>;
106 case FormatArgumentRule::UnsignedPtrDiff:
107 return std::is_same_v<Normalized, std::make_unsigned_t<ptrdiff_t>>;
108 case FormatArgumentRule::Pointer:
109 return is_pointer_like;
110 case FormatArgumentRule::Character:
111 return is_character_like;
112 case FormatArgumentRule::String:
113 return is_string_like;
114 case FormatArgumentRule::Float:
115 return is_float;
116 case FormatArgumentRule::LongDouble:
117 return is_long_double;
118 default:
119 return false;
120 }
121 }
122};
123
134template <typename... Args, size_t N, size_t... I>
135[[nodiscard]] consteval bool MatchesImpl(
136 const std::array<FormatArgumentInfo, N>& arguments, std::index_sequence<I...>)
137{
138 return (TypeTraits<Args>::MatchesRule(arguments[I].rule) && ...);
139}
140
150template <typename... Args, size_t N>
151[[nodiscard]] consteval bool Matches(const std::array<FormatArgumentInfo, N>& arguments)
152{
153 if constexpr (sizeof...(Args) != N)
154 {
155 return false;
156 }
157 else
158 {
159 return MatchesImpl<Args...>(arguments, std::make_index_sequence<N>{});
160 }
161}
162} // namespace LibXR::Print::Detail::FormatArgument
Internal C++ argument-type utilities shared by compile-time matching and runtime packing.
static consteval bool MatchesRule(FormatArgumentRule rule)
判断当前 C++ 实参类型是否满足某条编译期匹配规则。 / Returns whether this C++ argument type satisfies one compile-time rule.