Skip to content

Commit 6240185

Browse files
committed
Vutils
1 parent 66b5176 commit 6240185

File tree

7 files changed

+299
-0
lines changed

7 files changed

+299
-0
lines changed

Test/Sample.Misc.h

+7
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,12 @@ DEF_SAMPLE(Misc)
169169

170170
MessageBoxA(nullptr, "This message box just keep for the program running...", "", MB_OK);
171171

172+
// Easy Print
173+
{
174+
auto pids = vu::name_to_pid(ts("explorer.exe"));
175+
auto string = std::ep::stringify_container(pids);
176+
std::tcout << string << std::endl;
177+
}
178+
172179
return vu::VU_OK;
173180
}

Vutils.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@
329329
<ClInclude Include="3rdparty\UND\include\undname.h" />
330330
<ClInclude Include="3rdparty\WHW\WinHttpWrapper.h" />
331331
<ClInclude Include="include\3rdparty\BI\BigInt.hpp" />
332+
<ClInclude Include="include\3rdparty\EP\include\easyprint.hpp" />
332333
<ClInclude Include="include\3rdparty\NO\include\base\named_operator.hpp" />
333334
<ClInclude Include="include\3rdparty\NO\include\util\io_helpers.hpp" />
334335
<ClInclude Include="include\3rdparty\WHW\Types.h" />
@@ -399,6 +400,7 @@
399400
<None Include="include\inline\std.inl" />
400401
<None Include="include\inline\types.inl" />
401402
<None Include="include\inline\spechrs.inl" />
403+
<None Include="include\template\easyprint.tpl" />
402404
<None Include="include\template\handle.tpl" />
403405
<None Include="include\template\math.tpl" />
404406
<None Include="include\template\misc.tpl" />

Vutils.vcxproj.filters

+9
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@
6161
<Filter Include="Third Party Files\TE">
6262
<UniqueIdentifier>{8ca70d61-cc68-42db-ad04-82ef7fe42ab8}</UniqueIdentifier>
6363
</Filter>
64+
<Filter Include="Header Files\Third Files\EP">
65+
<UniqueIdentifier>{0e80967e-0e61-4762-98d0-e9774dcee22f}</UniqueIdentifier>
66+
</Filter>
6467
</ItemGroup>
6568
<ItemGroup>
6669
<ClInclude Include="include\Vutils.h">
@@ -150,6 +153,9 @@
150153
<ClInclude Include="3rdparty\TE\include\text_encoding_detect.h">
151154
<Filter>Third Party Files\TE</Filter>
152155
</ClInclude>
156+
<ClInclude Include="include\3rdparty\EP\include\easyprint.hpp">
157+
<Filter>Header Files\Third Files\EP</Filter>
158+
</ClInclude>
153159
</ItemGroup>
154160
<ItemGroup>
155161
<ClCompile Include="src\Vutils.cpp">
@@ -349,5 +355,8 @@
349355
<None Include="include\template\handle.tpl">
350356
<Filter>Header Files\Template Files</Filter>
351357
</None>
358+
<None Include="include\template\easyprint.tpl">
359+
<Filter>Header Files\Template Files</Filter>
360+
</None>
352361
</ItemGroup>
353362
</Project>

include/3rdparty/EP/README.TXT

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
easyprint
2+
https://github.com/hebaishi/easy-cpp-print.git
3+
https://github.com/vn-os/easy-cpp-print.git
4+
Oct 31, 2023
5+
<Unknown>
+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
#include <iostream>
2+
#include <sstream>
3+
#include <tuple>
4+
5+
#ifdef EASY_PRINT_WINDOWS
6+
7+
#include <windows.h>
8+
9+
namespace easyprint_helper // @refer to https://github.com/vic4key/Vutils.git
10+
{
11+
inline std::string __to_string_A(const std::wstring& string, const bool utf8)
12+
{
13+
std::string s;
14+
s.clear();
15+
16+
if (string.empty())
17+
{
18+
return s;
19+
}
20+
21+
int N = (int)string.length();
22+
23+
if (utf8)
24+
{
25+
N = WideCharToMultiByte(CP_UTF8, 0, string.c_str(), int(string.length()), NULL, 0, NULL, NULL);
26+
}
27+
28+
N += 1;
29+
30+
std::unique_ptr<char[]> p(new char[N]);
31+
if (p == nullptr)
32+
{
33+
return s;
34+
}
35+
36+
ZeroMemory(p.get(), N);
37+
38+
WideCharToMultiByte(utf8 ? CP_UTF8 : CP_ACP, WC_COMPOSITECHECK, string.c_str(), -1, p.get(), N, NULL, NULL);
39+
40+
s.assign(p.get());
41+
42+
return s;
43+
}
44+
45+
inline std::wstring __to_string_W(const std::string& string, const bool utf8)
46+
{
47+
std::wstring s;
48+
s.clear();
49+
50+
if (string.empty())
51+
{
52+
return s;
53+
}
54+
55+
int N = (int)string.length();
56+
57+
if (utf8)
58+
{
59+
N = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), int(string.length()), NULL, 0);
60+
}
61+
62+
N += 1;
63+
64+
std::unique_ptr<wchar_t[]> p(new wchar_t[N]);
65+
if (p == nullptr)
66+
{
67+
s.clear();
68+
}
69+
70+
ZeroMemory(p.get(), 2 * N);
71+
72+
MultiByteToWideChar(utf8 ? CP_UTF8 : CP_ACP, 0, string.c_str(), -1, p.get(), 2 * N);
73+
74+
s.assign(p.get());
75+
76+
return s;
77+
}
78+
} // easyprint_helper
79+
80+
#endif // EASY_PRINT_WINDOWS
81+
82+
namespace easyprint {
83+
84+
template <typename ...Targs>
85+
struct default_delimiter {
86+
static constexpr const char* start_delimiter = "{";
87+
static constexpr const char* element_delimiter = ", ";
88+
static constexpr const char* end_delimiter = "}";
89+
};
90+
91+
template <size_t I> struct tuple_delimiter {
92+
static constexpr const char* value = default_delimiter<int>::element_delimiter;
93+
};
94+
95+
template <> struct tuple_delimiter<0> { static constexpr const char* value = default_delimiter<int>::start_delimiter; };
96+
97+
template <typename T> struct is_tuple { static const bool value = false; };
98+
99+
template <typename... Targs> struct is_tuple<std::tuple<Targs...>> {
100+
static const bool value = true;
101+
};
102+
103+
// Helper struct to determine
104+
// whether a type has a const_iterator typedef
105+
template <typename T> struct is_const_iterable {
106+
107+
template <typename C> static std::true_type f(typename C::const_iterator *);
108+
109+
template <typename C> static std::false_type f(...);
110+
111+
typedef decltype(f<T>(0)) type;
112+
};
113+
114+
template <typename T>
115+
using is_const_iterable_v = typename is_const_iterable<T>::type;
116+
117+
template <typename T>
118+
inline void print_iterator_helper(std::false_type, std::ostream &os, const T &cont) {
119+
os << cont;
120+
}
121+
122+
inline void print_iterator_helper(std::false_type, std::ostream &os, const char *cont) {
123+
os << "\"" << cont << "\"";
124+
}
125+
126+
template <typename TChar>
127+
inline void print_iterator_helper(std::true_type, std::ostream &os,
128+
const std::basic_string<TChar> &cont) {
129+
os << "\"" << cont << "\"";
130+
}
131+
132+
#ifdef EASY_PRINT_WINDOWS
133+
template <>
134+
inline void print_iterator_helper(std::true_type, std::ostream& os,
135+
const std::basic_string<wchar_t>& cont) {
136+
os << "\"" << easyprint_helper::__to_string_A(cont, true) << "\"";
137+
}
138+
#endif // EASY_PRINT_WINDOWS
139+
140+
// Functions to recursively print tuples
141+
template <size_t I, typename T>
142+
typename std::enable_if<(!is_tuple<T>::value), void>::type
143+
print_tuple(std::ostream &os, const T &cont) {
144+
print_iterator_helper(is_const_iterable_v<T>(), os, cont);
145+
}
146+
147+
template <size_t I, typename... Targs>
148+
typename std::enable_if<(I == sizeof...(Targs)), void>::type
149+
print_tuple(std::ostream &os, const std::tuple<Targs...> &tup) {
150+
os << default_delimiter<std::tuple<Targs...>>::end_delimiter;
151+
}
152+
153+
template <size_t I, typename... Targs>
154+
typename std::enable_if<(I < sizeof...(Targs)), void>::type
155+
print_tuple(std::ostream &os, const std::tuple<Targs...> &tup) {
156+
os << tuple_delimiter<I>::value;
157+
auto val = std::get<I>(tup);
158+
print_tuple<0>(os, val);
159+
print_tuple<I + 1>(os, tup);
160+
}
161+
162+
template <typename T>
163+
inline void print_iterator_helper(std::true_type, std::ostream &os, const T &cont);
164+
165+
// Pair specialization
166+
template <typename T1, typename T2>
167+
inline void print_iterator_helper(std::false_type, std::ostream &os,
168+
const std::pair<T1, T2> &cont) {
169+
os << default_delimiter<decltype(cont)>::start_delimiter;
170+
print_iterator_helper(is_const_iterable_v<T1>(), os, cont.first);
171+
os << default_delimiter<decltype(cont)>::element_delimiter;
172+
print_iterator_helper(is_const_iterable_v<T2>(), os, cont.second);
173+
os << default_delimiter<decltype(cont)>::end_delimiter;
174+
}
175+
176+
// Specialisation for tuples
177+
// Passes control to tuple printing
178+
// functions
179+
template <typename... Targs>
180+
inline void print_iterator_helper(std::false_type, std::ostream &os,
181+
const std::tuple<Targs...> &cont) {
182+
print_tuple<0>(os, cont);
183+
}
184+
185+
// Recursive function to print iterators
186+
template <typename T>
187+
inline void print_iterator_helper(std::true_type, std::ostream &os, const T &cont) {
188+
os << default_delimiter<decltype(cont)>::start_delimiter;
189+
if (!cont.empty()) {
190+
auto it = cont.begin();
191+
print_iterator_helper(is_const_iterable_v<typename T::value_type>{}, os, *it);
192+
it++;
193+
for (; it != cont.cend(); it++) {
194+
os << default_delimiter<decltype(cont)>::element_delimiter;
195+
print_iterator_helper(is_const_iterable_v<typename T::value_type>{}, os, *it);
196+
}
197+
}
198+
os << default_delimiter<decltype(cont)>::end_delimiter;
199+
}
200+
201+
// User-facing functions
202+
template <typename T>
203+
inline std::string stringify_A(const T &container) {
204+
std::stringstream ss;
205+
print_iterator_helper(is_const_iterable_v<T>(), ss, container);
206+
return ss.str();
207+
}
208+
209+
template <typename T>
210+
inline std::wstring stringify_W(const T& container) {
211+
std::stringstream ss;
212+
print_iterator_helper(is_const_iterable_v<T>(), ss, container);
213+
return easyprint_helper::__to_string_W(ss.str(), true);
214+
}
215+
216+
template <typename T>
217+
inline void print_A(const T &container) {
218+
std::cout << stringify_A(container);
219+
}
220+
221+
template <typename T>
222+
inline void print_W(const T& container) {
223+
std::wcout << stringify_W(container);
224+
}
225+
226+
#ifdef _UNICODE
227+
#define stringify stringify_W
228+
#define print print_W
229+
#else // _UNICODE
230+
#define stringify stringify_A
231+
#define print print_A
232+
#endif // _UNICODE
233+
234+
} // namespace easyprint

include/Vutils.h

+4
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ using namespace WinHttpWrapper;
163163

164164
#include "template/nameop.tpl"
165165

166+
// Easy Print
167+
168+
#include "template/easyprint.tpl"
169+
166170
namespace vu
167171
{
168172

include/template/easyprint.tpl

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @file easyprint.tpl
3+
* @author Vic P.
4+
* @brief Template for Easy Print
5+
*/
6+
7+
/**
8+
* Easy Print
9+
*/
10+
11+
#pragma once
12+
13+
#define EASY_PRINT_WINDOWS
14+
#include "3rdparty/EP/include/easyprint.hpp"
15+
16+
#include <string>
17+
18+
namespace std { namespace ep {
19+
20+
template <typename T>
21+
std::string stringify_container_A(const T& container)
22+
{
23+
return easyprint::stringify_A(container);
24+
}
25+
26+
template <typename T>
27+
std::wstring stringify_container_W(const T& container)
28+
{
29+
return easyprint::stringify_W(container);
30+
}
31+
32+
}} // std::ep
33+
34+
#ifdef _UNICODE
35+
#define stringify_container stringify_container_W
36+
#else // _UNICODE
37+
#define stringify_container stringify_container_A
38+
#endif // _UNICODE

0 commit comments

Comments
 (0)