-
Notifications
You must be signed in to change notification settings - Fork 2
/
coloredconsole.h
92 lines (79 loc) · 2.91 KB
/
coloredconsole.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#pragma once
#include <iostream>
#include <string>
#include <string_view>
namespace coloredconsole
{
/// <summary>
/// function for actual colorization of ERROR and Warning words
/// </summary>
/// <param name="os"> std::cout actually</param>
/// <param name="sv">string view to search ERROR and Warning words for colorization</param>
void ColorizeWords(std::ostream& os, const std::string_view sv);
template<typename T>
struct is_char_array : std::false_type {}; // by default the type is not char array
template<std::size_t N>
struct is_char_array<char[N]> : std::true_type {}; // this is char array and compiler knows it's size
template<std::size_t N>
struct is_char_array<const char[N]> : std::true_type {}; // this is char array and compiler knows it's size
template<typename T> // not a constant from this moment
constexpr bool is_char_array_v = is_char_array<std::remove_cvref_t<T>>::value;
/// <summary>
/// colorize ERROR and Warning words with help of this class
/// </summary>
/// <typeparam name="T">Type to wrap</typeparam>
template<typename T>
class Console {
public:
Console(T&& value): value_(std::forward<T>(value)) {}
/// <summary>
/// any wrapped with Console type will have this operator
/// </summary>
friend std::ostream& operator<<(std::ostream& os, const Console& logger)
{
using BareT = std::remove_cvref_t<T>;
if constexpr (is_char_array_v<BareT>)
{
constexpr auto length = sizeof(BareT) / sizeof(char) - 1;
ColorizeWords(os, std::string_view(logger.value_, length));
}
else if constexpr (
std::is_same_v<std::string_view, BareT>
|| std::is_same_v<const std::string_view, BareT>
)
{
ColorizeWords(os, logger.value_);
}
else if constexpr (
std::is_same_v<char*, BareT>
|| std::is_same_v<const char*, BareT>
|| std::is_same_v<const char* const, BareT>
|| std::is_same_v<char* const, BareT>
)
{
ColorizeWords(os, std::string_view(logger.value_, strlen(logger.value_)));
}
else if constexpr (
std::is_same_v<std::string, BareT>
|| std::is_same_v<const std::string, BareT>
)
{
ColorizeWords(os, {logger.value_.c_str(), logger.value_.length()});
}
else
{
os << logger.value_;
}
return os;
}
private:
T value_;
};
/// <summary>
/// Create Wrapped instance
/// </summary>
template<typename T>
Console<T> toconsole(T&& value) {
return Console<T>(std::forward<T>(value));
}
};