header_utils
Loading...
Searching...
No Matches
stringification.h
1
4
5#pragma once
6
7#include "string_ops.h"
8
9namespace ghassanpl
10{
11 template <std::same_as<char> T>
12 std::string to_string(T c) { return std::string{c}; }
13 template <typename T>
14 requires (!std::same_as<T, char> && std::integral<T>)
15 std::string to_string(T val) { return std::to_string(val); }
16 template <std::floating_point T>
17 std::string to_string(T val)
18 {
19 const auto len = static_cast<size_t>(::snprintf(nullptr, 0, "%g", val));
20 std::string str(len, '\0');
21 ::sprintf_s(&str[0], len+ 1, "%g", val);
22 return str;
23 }
24 template <typename T>
25 requires std::constructible_from<std::string_view, T>
26 std::string to_string(T&& val) { return std::string{std::string_view{std::forward<T>(val)}}; }
27 inline std::string to_string(nullptr_t) { return "null"; }
28}
29
31
32namespace ghassanpl
33{
35
36 template <bool TO_STRING>
38 {
39 std::string& result;
40
41 template <typename... ARGS>
42 bool operator()(ARGS&&... args)
43 {
44 ((result += ghassanpl::to_string(args)), ...);
45 return true;
46 }
47 };
48
49 template <typename T>
50 concept from_charsable = requires (const char* a, T& to) { { std::from_chars(a, a, to) } -> std::same_as<std::from_chars_result>; };
51
52 template <typename T>
53 bool eat_from_string(std::string_view& from, T&& val)
54 {
55 if constexpr (std::is_reference_v<T>)
56 {
57 if constexpr (std::same_as<T, char>)
58 {
59 if (from.empty()) return false;
60 val = from[0];
61 from.remove_prefix(1);
62 return true;
63 }
64 else if constexpr (from_charsable<T>)
65 {
66 auto [ptr, ec] = string_ops::from_chars(from, val);
67 if (ec == std::errc{})
68 {
69 from = ghassanpl::string_ops::make_sv(ptr, from.end());
70 return true;
71 }
72 return false;
73 }
74 else
75 {
76 make_sv(from, val);
77 }
78 }
79 else
80 {
81 if constexpr (std::same_as<T, char> || std::convertible_to<T, std::string_view>)
82 {
84 }
85 else
86 {
87 make_sv(from, val);
88 }
89 }
90 }
91
92 template <>
93 struct string_stringifier<false>
94 {
95 std::string_view from;
96
97 template <typename... ARGS>
98 bool operator()(ARGS&&... args)
99 {
100 return ((ghassanpl::eat_from_string(from, std::forward<ARGS>(args))) && ...);
101 }
102 };
103
104 template <typename T, template<bool> typename STRINGIFIER = string_stringifier>
105 requires requires (STRINGIFIER<true> str, T val) { stringify(str, val); }
106 std::string to_string(T&& val)
107 {
108 std::string result;
109 STRINGIFIER<true> str{result};
110 stringify(str, std::forward<T>(val));
111 return result;
112 }
113
114 template <typename T, template<bool> typename STRINGIFIER = string_stringifier>
115 requires requires (STRINGIFIER<false> str, T val) { stringify(str, val); }
116 bool from_string(std::string_view val, T& target)
117 {
119 if (!stringify(str, target))
120 return false;
121 return true;
122 }
123
124 template <typename T, template<bool> typename STRINGIFIER = string_stringifier>
125 requires requires (STRINGIFIER<false> str, T val) { stringify(str, val); }
126 T from_string(std::string_view val)
127 {
128 T result{};
130 if (!stringify(str, result))
131 return {};
132 return result;
133 }
134}
135
136template <typename T>
137requires requires (ghassanpl::string_stringifier<true> str, T val) { stringify(str, val); }
138struct std::formatter<T> : std::formatter<std::string>
139{
140 template<typename U, class FormatContext>
141 auto format(U&& t, FormatContext& fc) const
142 {
143 std::string result;
145 stringify(str, std::forward<U>(t));
146 return std::formatter<std::string>::format(std::move(result), fc);
147 }
148};
149
150template <typename T>
151requires requires (T val) { { (std::string_view)val } -> std::same_as<std::string_view>; } && (!std::convertible_to<T, std::string_view>)
152struct std::formatter<T> : std::formatter<std::string_view>
153{
154 template<typename U, class FormatContext>
155 auto format(U&& t, FormatContext& fc) const
156 {
157 return std::formatter<std::string_view>::format((std::string_view)std::forward<U>(t), fc);
158 }
159};
160
161/*
162template <typename T>
163requires (requires (T val) { ghassanpl::to_string(val); }) && (!requires (T val) { std::to_string(val); })
164struct std::formatter<T> : std::formatter<std::string>
165{
166 template<typename U, class FormatContext>
167 auto format(U&& t, FormatContext& fc) const
168 {
169 return std::formatter<std::string>::format(ghassanpl::to_string(std::forward<U>(t)), fc);
170 }
171};
172*/
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
constexpr CONTAINER to(RANGE &&range, TYPES &&... args)
to<container>();
Definition ranges.h:369
auto from_chars(std::string_view str, T &value, const int base=10) noexcept
A version of std::from_chars that takes a std::string_view as the first argument.
char consume(std::string_view &str)
Consumes and returns the first character in the str, or \0 if no more characters.
Definition string_ops.h:652
Primary namespace for everything in this library.
Definition align+rec2.h:10
NOTE: The below is a MAJOR WORK IN PROGRESS.