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{
24template <typename T>
26{
27 using Decayed = std::remove_cvref_t<T>;
28 using Normalized =
29 typename std::conditional_t<std::is_enum_v<Decayed>, std::underlying_type<Decayed>,
30 std::type_identity<Decayed>>::type;
31
32 static constexpr bool is_signed_integer =
33 std::is_integral_v<Normalized> && !std::is_same_v<Normalized, bool> &&
34 std::is_signed_v<Normalized>;
35 static constexpr bool is_unsigned_integer =
36 std::is_integral_v<Normalized> && !std::is_same_v<Normalized, bool> &&
37 std::is_unsigned_v<Normalized>;
38 static constexpr bool is_default_signed_integer =
39 is_signed_integer && sizeof(Normalized) <= sizeof(int);
40 static constexpr bool is_default_unsigned_integer =
41 is_unsigned_integer && sizeof(Normalized) <= sizeof(unsigned int);
42 static constexpr bool is_char_array =
43 std::is_array_v<Decayed> &&
44 std::is_same_v<std::remove_cv_t<std::remove_extent_t<Decayed>>, char>;
45 static constexpr bool is_c_string =
46 std::is_same_v<Decayed, const char*> || std::is_same_v<Decayed, char*> ||
47 is_char_array;
48 static constexpr bool is_string_like =
49 is_c_string || 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 = std::is_same_v<Decayed, float> ||
57 std::is_same_v<Decayed, double>;
58 static constexpr bool is_long_double = std::is_same_v<Decayed, long double>;
59
64 [[nodiscard]] static consteval bool MatchesRule(FormatArgumentRule rule)
65 {
66 if (rule == FormatArgumentRule::None)
67 {
68 return true;
69 }
70
71 switch (rule)
72 {
73 case FormatArgumentRule::SignedAny:
74 return is_default_signed_integer;
75 case FormatArgumentRule::SignedChar:
76 return std::is_same_v<Normalized, signed char>;
77 case FormatArgumentRule::SignedShort:
78 return std::is_same_v<Normalized, short>;
79 case FormatArgumentRule::SignedLong:
80 return std::is_same_v<Normalized, long>;
81 case FormatArgumentRule::SignedLongLong:
82 return std::is_same_v<Normalized, long long>;
83 case FormatArgumentRule::SignedIntMax:
84 return std::is_same_v<Normalized, intmax_t>;
85 case FormatArgumentRule::SignedSize:
86 return std::is_same_v<Normalized, std::make_signed_t<size_t>>;
87 case FormatArgumentRule::SignedPtrDiff:
88 return std::is_same_v<Normalized, ptrdiff_t>;
89 case FormatArgumentRule::UnsignedAny:
90 return is_default_unsigned_integer;
91 case FormatArgumentRule::UnsignedChar:
92 return std::is_same_v<Normalized, unsigned char>;
93 case FormatArgumentRule::UnsignedShort:
94 return std::is_same_v<Normalized, unsigned short>;
95 case FormatArgumentRule::UnsignedLong:
96 return std::is_same_v<Normalized, unsigned long>;
97 case FormatArgumentRule::UnsignedLongLong:
98 return std::is_same_v<Normalized, unsigned long long>;
99 case FormatArgumentRule::UnsignedIntMax:
100 return std::is_same_v<Normalized, uintmax_t>;
101 case FormatArgumentRule::UnsignedSize:
102 return std::is_same_v<Normalized, size_t>;
103 case FormatArgumentRule::UnsignedPtrDiff:
104 return std::is_same_v<Normalized, std::make_unsigned_t<ptrdiff_t>>;
105 case FormatArgumentRule::Pointer:
106 return is_pointer_like;
107 case FormatArgumentRule::Character:
108 return is_character_like;
109 case FormatArgumentRule::String:
110 return is_string_like;
111 case FormatArgumentRule::Float:
112 return is_float;
113 case FormatArgumentRule::LongDouble:
114 return is_long_double;
115 default:
116 return false;
117 }
118 }
119};
120
125template <typename... Args, size_t N, size_t... I>
126[[nodiscard]] consteval bool MatchesImpl(
127 const std::array<FormatArgumentInfo, N>& arguments, std::index_sequence<I...>)
128{
129 return (TypeTraits<Args>::MatchesRule(arguments[I].rule) && ...);
130}
131
137template <typename... Args, size_t N>
138[[nodiscard]] consteval bool Matches(const std::array<FormatArgumentInfo, N>& arguments)
139{
140 if constexpr (sizeof...(Args) != N)
141 {
142 return false;
143 }
144 else
145 {
146 return MatchesImpl<Args...>(arguments, std::make_index_sequence<N>{});
147 }
148}
149} // namespace LibXR::Print::Detail::FormatArgument
Internal C++ argument-type utilities shared by compile-time matching and runtime packing.
static consteval bool MatchesRule(FormatArgumentRule rule)
Returns whether this C++ argument type satisfies one compile-time rule.