Skip to content

Commit c8889f1

Browse files
committed
Add formatted output
1 parent 6c36ff1 commit c8889f1

File tree

7 files changed

+222
-82
lines changed

7 files changed

+222
-82
lines changed

.clang-format

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
BasedOnStyle: LLVM
2+
3+
AccessModifierOffset: -4
4+
AlignAfterOpenBracket: AlwaysBreak
5+
AlignConsecutiveAssignments: None
6+
AlignConsecutiveDeclarations: None
7+
AlignEscapedNewlines: DontAlign
8+
AlignOperands: Align
9+
AlignTrailingComments: true
10+
AllowAllParametersOfDeclarationOnNextLine: true
11+
AllowShortBlocksOnASingleLine: Never
12+
AllowShortCaseLabelsOnASingleLine: false
13+
AllowShortFunctionsOnASingleLine: Inline
14+
AllowShortIfStatementsOnASingleLine: Never
15+
AllowShortLoopsOnASingleLine: false
16+
AlwaysBreakAfterReturnType: None
17+
AlwaysBreakBeforeMultilineStrings: false
18+
AlwaysBreakTemplateDeclarations: Yes
19+
BinPackArguments: false
20+
BinPackParameters: false
21+
BraceWrapping:
22+
AfterClass: false
23+
AfterControlStatement: Never
24+
AfterEnum: false
25+
AfterFunction: false
26+
AfterNamespace: false
27+
AfterObjCDeclaration: false
28+
AfterStruct: false
29+
AfterUnion: false
30+
BeforeCatch: false
31+
BeforeElse: false
32+
IndentBraces: false
33+
SplitEmptyFunction: false
34+
SplitEmptyRecord: false
35+
SplitEmptyNamespace: false
36+
BreakBeforeBinaryOperators: All
37+
BreakBeforeBraces: Custom
38+
BreakBeforeInheritanceComma: false
39+
BreakBeforeTernaryOperators: true
40+
BreakConstructorInitializersBeforeComma: false
41+
BreakConstructorInitializers: BeforeComma
42+
BreakAfterJavaFieldAnnotations: false
43+
BreakStringLiterals: true
44+
ColumnLimit: 100
45+
CommentPragmas: '^ IWYU pragma:'
46+
CompactNamespaces: false
47+
ConstructorInitializerAllOnOneLineOrOnePerLine: false
48+
ConstructorInitializerIndentWidth: 4
49+
ContinuationIndentWidth: 4
50+
Cpp11BracedListStyle: true
51+
DerivePointerAlignment: false
52+
DisableFormat: false
53+
ExperimentalAutoDetectBinPacking: false
54+
FixNamespaceComments: true
55+
ForEachMacros:
56+
- forever # avoids { wrapped to next line
57+
- foreach
58+
- Q_FOREACH
59+
- BOOST_FOREACH
60+
IncludeCategories:
61+
- Regex: '^<Q.*'
62+
Priority: 200
63+
IncludeIsMainRegex: '(Test)?$'
64+
IndentCaseLabels: false
65+
IndentWidth: 4
66+
IndentWrappedFunctionNames: false
67+
InsertBraces: false
68+
JavaScriptQuotes: Leave
69+
JavaScriptWrapImports: true
70+
KeepEmptyLinesAtTheStartOfBlocks: false
71+
# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
72+
MacroBlockBegin: ""
73+
MacroBlockEnd: ""
74+
MaxEmptyLinesToKeep: 1
75+
NamespaceIndentation: None
76+
ObjCBlockIndentWidth: 4
77+
ObjCSpaceAfterProperty: false
78+
ObjCSpaceBeforeProtocolList: true
79+
PenaltyBreakAssignment: 88
80+
PenaltyBreakBeforeFirstCallParameter: 300
81+
PenaltyBreakComment: 500
82+
PenaltyBreakFirstLessLess: 400
83+
PenaltyBreakString: 600
84+
PenaltyExcessCharacter: 50
85+
PenaltyReturnTypeOnItsOwnLine: 300
86+
PointerAlignment: Right
87+
ReflowComments: false
88+
SortIncludes: CaseSensitive
89+
SortUsingDeclarations: true
90+
SpaceAfterCStyleCast: true
91+
SpaceAfterTemplateKeyword: false
92+
SpaceBeforeAssignmentOperators: true
93+
SpaceBeforeParens: ControlStatements
94+
SpaceInEmptyParentheses: false
95+
SpacesBeforeTrailingComments: 1
96+
SpacesInAngles: Never
97+
SpacesInContainerLiterals: false
98+
SpacesInCStyleCastParentheses: false
99+
SpacesInParentheses: false
100+
SpacesInSquareBrackets: false
101+
Standard: c++20
102+
TabWidth: 4
103+
UseTab: Never

CMakeLists.txt

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
cmake_minimum_required(VERSION 3.25)
22
project(logger)
3-
43
set(CMAKE_CXX_STANDARD 20)
54

6-
75
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/lib/${CMAKE_BUILD_TYPE})
86
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/bin/${CMAKE_BUILD_TYPE})
9-
include_directories(src)
7+
include_directories(src include)
108

119
add_library(
12-
logger STATIC
13-
src/logger.cpp
14-
src/logger.hpp
10+
logger STATIC
11+
src/logger.cpp
12+
include/logger.hpp
13+
src/string.hpp
1514
)
1615

1716
add_executable(
18-
example
19-
src/logger.cpp
20-
src/logger.hpp
21-
src/example/example.cpp
17+
example
18+
src/logger.cpp
19+
include/logger.hpp
20+
src/example/example.cpp
21+
src/string.hpp
2222
)

include/logger.hpp

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#pragma once
2+
3+
#include "../src/string.hpp"
4+
#include <fstream>
5+
#include <optional>
6+
#include <sstream>
7+
8+
namespace Logger {
9+
enum class LogLevel {
10+
None = 0,
11+
Fatal = 1,
12+
Error = 2,
13+
Warning = 4,
14+
Info = 8,
15+
All = Fatal | Error | Warning | Info
16+
};
17+
18+
constexpr LogLevel operator|(LogLevel a, LogLevel b) {
19+
return static_cast<LogLevel>(static_cast<char>(a) | static_cast<char>(b));
20+
}
21+
22+
constexpr LogLevel operator&(LogLevel a, LogLevel b) {
23+
return static_cast<LogLevel>(static_cast<char>(a) & static_cast<char>(b));
24+
}
25+
26+
constexpr LogLevel operator~(LogLevel level) {
27+
return static_cast<LogLevel>(~static_cast<char>(level));
28+
}
29+
30+
inline LogLevel logLevel = LogLevel::All;
31+
inline bool showTimestamp = true;
32+
inline bool useColor = false;
33+
34+
std::string logLevelToString(LogLevel level);
35+
std::string getTimestamp();
36+
37+
#if _WIN32
38+
int getColor(LogLevel level);
39+
void setWindowsColor(int color);
40+
#else
41+
std::string getColor(LogLevel level);
42+
#endif
43+
44+
class LogStream {
45+
public:
46+
explicit LogStream(LogLevel level);
47+
LogStream(LogLevel level, const std::string &fileName);
48+
~LogStream();
49+
50+
template<typename T>
51+
LogStream &operator<<(const T &message) {
52+
std::string str = m_strStream.str();
53+
m_strStream.str(String::formatString(str, message));
54+
55+
return *this;
56+
}
57+
58+
private:
59+
std::optional<std::ofstream> m_outFileStream = std::nullopt;
60+
std::ostringstream m_strStream;
61+
LogLevel m_messageLogLevel;
62+
};
63+
64+
LogStream log(LogLevel level);
65+
LogStream logToFile(LogLevel level, const std::string &fileName);
66+
} // namespace Logger
67+
68+
using Logger::LogLevel;

src/example/example.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22

33
int main() {
44
using namespace Logger;
5+
6+
// Color (off by default)
57
useColor = true;
6-
log(LogLevel::Error) << "Hello, Error!";
7-
log(LogLevel::Warning) << "Hello, Warning!";
8+
9+
// Log levels
810
log(LogLevel::Info) << "Hello, Info!";
11+
log(LogLevel::Warning) << "Hello, Warning!";
12+
log(LogLevel::Error) << "Hello, Error!";
913
// log(LogLevel::Fatal) << "Hello, Fatal!";
14+
// ^ Try and uncomment this
15+
16+
// Formatted output
17+
log(LogLevel::Info) << "My name is {}, and I am {} years old." << "John" << 35;
18+
19+
// Output to file
1020
logToFile(LogLevel::Info, "Example.log") << "Hello, Info!";
1121
}

src/logger.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ std::string Logger::logLevelToString(const LogLevel level) {
1818
case LogLevel::Info: return "[INF]";
1919
default:
2020
log(LogLevel::Error) << "Invalid log level specified!";
21-
return "\0";
21+
return "[UNK]";
2222
}
2323
}
2424

src/logger.hpp

-69
This file was deleted.

src/string.hpp

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <sstream>
4+
#include <string>
5+
6+
namespace String {
7+
8+
template <typename T>
9+
std::string to_string(const T &value) {
10+
std::ostringstream oss;
11+
oss << value;
12+
return oss.str();
13+
}
14+
15+
template<typename T>
16+
std::string formatString(const std::string &string, const T &value) {
17+
if (string.find("{}") == std::string::npos) return string + to_string(value);
18+
19+
std::string out = string;
20+
21+
if (size_t pos = out.find("{}"); pos != std::string::npos) {
22+
return out.replace(pos, 2, to_string(value));
23+
}
24+
25+
return out;
26+
}
27+
28+
} // namespace String

0 commit comments

Comments
 (0)