Melon
A C++ library designed for RadishOS.
Loading...
Searching...
No Matches
Fmt.hpp
1#pragma once
2
3#include "String.hpp"
4#include "Conversion.hpp"
5#include "Typing.hpp"
6
7#include <concepts>
8#include <type_traits>
9
11namespace Melon::Fmt
12{
17 template<typename T>
18 struct IsSpecialValue : std::false_type
19 {};
20
22 template<typename T>
23 struct IsSpecialValue<Conversion::BinaryValue<T>> : std::true_type
24 {};
25
27 template<typename T>
28 struct IsSpecialValue<Conversion::OctalValue<T>> : std::true_type
29 {};
30
32 template<typename T>
33 struct IsSpecialValue<Conversion::HexadecimalValue<T>> : std::true_type
34 {};
35
37 template<typename T>
39
41 template<typename T>
42 concept Formattable =
43 std::same_as<std::remove_cvref_t<T>, char>
44 or std::same_as<std::remove_cvref_t<T>, String::String>
45 or std::same_as<std::remove_cvref_t<T>, int>
46 or std::same_as<std::remove_cvref_t<T>, long>
47 or std::same_as<std::remove_cvref_t<T>, long long>
48 or std::same_as<std::remove_cvref_t<T>, unsigned int>
49 or std::same_as<std::remove_cvref_t<T>, unsigned long>
50 or std::same_as<std::remove_cvref_t<T>, unsigned long long>
51 or std::same_as<std::remove_cvref_t<T>, Typing::Int8>
52 or std::same_as<std::remove_cvref_t<T>, Typing::Int16>
53 or std::same_as<std::remove_cvref_t<T>, Typing::Int32>
54 or std::same_as<std::remove_cvref_t<T>, Typing::Int64>
55 or std::same_as<std::remove_cvref_t<T>, Typing::Uint8>
56 or std::same_as<std::remove_cvref_t<T>, Typing::Uint16>
57 or std::same_as<std::remove_cvref_t<T>, Typing::Uint32>
58 or std::same_as<std::remove_cvref_t<T>, Typing::Uint64>
60 ;
61
68 template<Formattable T, typename... ARGS>
69 constexpr void formatArgs(String::String &out, const String::String &fmt, Typing::USize &idx, T &&arg, ARGS &&...args)
70 {
71 for (; idx < fmt.length(); ++idx) {
72 if (fmt[idx] != '{') {
73 out.appendChar(fmt[idx]);
74 continue;
75 }
76
77 ++idx;
78 if (idx >= fmt.length())
79 return;
80
81 if (fmt[idx] == '}') {
82 // "{}" found, so we expect a parameter
83 if constexpr (std::is_same<std::remove_cvref_t<T>, char>::value) {
84 out.appendChar(arg);
85 } else if constexpr (std::is_same<std::remove_cvref_t<T>, String::String>::value)
86 out += arg;
87 else if constexpr (
88 std::is_same<std::remove_cvref_t<T>, int>::value
89 or std::is_same<std::remove_cvref_t<T>, long>::value
90 or std::is_same<std::remove_cvref_t<T>, long long>::value
91 ) {
92 out += Conversion::intToString<std::remove_cvref_t<T>>(arg, Conversion::Base::Decimal);
93 } else if constexpr (
94 std::is_same<std::remove_cvref_t<T>, unsigned int>::value
95 or std::is_same<std::remove_cvref_t<T>, unsigned long>::value
96 or std::is_same<std::remove_cvref_t<T>, unsigned long long>::value
97 ) {
98 out += Conversion::uintToString<std::remove_cvref_t<T>>(arg, Conversion::Base::Decimal);
99 } else if constexpr (IsSpecialValueV<T>) {
100 using InnerType = std::remove_cvref_t<decltype(arg.value)>;
101 out += Conversion::uintToString<InnerType>(arg.value, std::remove_cvref_t<T>::base);
102 }
103
104 ++idx;
105 if constexpr (sizeof...(ARGS) > 0) {
106 formatArgs(out, fmt, idx, static_cast<ARGS &&>(args)...);
107 } else {
108 for (; idx < fmt.length(); ++idx)
109 out.appendChar(fmt[idx]);
110 }
111 return;
112 }
113 }
114 }
115
117 constexpr void formatArgs(String::String &out, const String::String &fmt, Typing::USize &idx)
118 {
119 for (; idx < fmt.length(); ++idx)
120 out.appendChar(fmt[idx]);
121 }
122
128 template<typename... ARGS>
129 String::String formatString(const String::String &str, ARGS &&...args)
130 {
131 String::String new_str;
132 Typing::USize idx = 0;
133
134 formatArgs(new_str, str, idx, static_cast<ARGS &&>(args)...);
135
136 return new_str;
137 }
138} // namespace Melon::Fmt
A dynamic string.
Definition String.hpp:11
Typing::USize length(this const String &self)
Gets the length of the string.
Definition String.cpp:47
void appendChar(this String &self, char ch)
Appends a character to the string.
Definition String.cpp:62
Makes sure that T is supported by formatArgs().
Definition Fmt.hpp:42
Contains functions to convert types into other types.
Definition Conversion.hpp:10
String::String intToString(T value, Base base)
Convert an integer to a String::String.
Definition Conversion.hpp:76
String::String uintToString(T value, Base base)
Convert an unsigned integer to a String::String.
Definition Conversion.hpp:110
Contains functions for string formatting.
Definition Fmt.hpp:12
constexpr bool IsSpecialValueV
Alias to avoid typing IsSpecialValue<T>::value.
Definition Fmt.hpp:38
constexpr void formatArgs(String::String &out, const String::String &fmt, Typing::USize &idx, T &&arg, ARGS &&...args)
Format a string.
Definition Fmt.hpp:69
String::String formatString(const String::String &str, ARGS &&...args)
Format a string.
Definition Fmt.hpp:129
int8_t Int8
Signed 8-bit integer.
Definition Typing.hpp:15
int64_t Int64
Signed 64-bit integer.
Definition Typing.hpp:21
size_t USize
Biggest unsigned type.
Definition Typing.hpp:38
uint8_t Uint8
Unsigned 8-bit integer.
Definition Typing.hpp:28
uint32_t Uint32
Unsigned 32-bit integer.
Definition Typing.hpp:32
uint16_t Uint16
Unsigned 16-bit integer.
Definition Typing.hpp:30
uint64_t Uint64
Unsigned 64-bit integer.
Definition Typing.hpp:34
int16_t Int16
Signed 16-bit integer.
Definition Typing.hpp:17
int32_t Int32
Signed 32-bit integer.
Definition Typing.hpp:19
Default behaviour for every type T.
Definition Fmt.hpp:19