Skip to content

Commit 794d353

Browse files
committed
add missing files
1 parent 4bd0915 commit 794d353

5 files changed

Lines changed: 366 additions & 0 deletions

File tree

include/MGIS/Context.ixx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*!
2+
* \file MGIS/Context.ixx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 24/02/2026
6+
*/
7+
8+
#ifndef LIB_MGIS_CONTEXT_IXX
9+
#define LIB_MGIS_CONTEXT_IXX
10+
11+
namespace mgis {
12+
13+
template <typename... Args>
14+
std::ostream &Context::log(const VerbosityLevel l, Args &&...args) noexcept {
15+
auto &os = this->log();
16+
if (this->getVerbosityLevel() >= l) {
17+
(os << ... << std::forward<Args>(args));
18+
os << std::endl;
19+
}
20+
return os;
21+
} // end of log
22+
23+
template <typename... Args>
24+
void Context::warning(Args &&...args) noexcept {
25+
mgis::warning(this->log(), std::forward<Args>(args)...);
26+
} // end of debug
27+
28+
template <typename... Args>
29+
void Context::debug(Args &&...args) noexcept {
30+
if (getVerbosityLevel() >= verboseDebug) {
31+
mgis::debug(this->log(), std::forward<Args>(args)...);
32+
}
33+
} // end of debug
34+
35+
} // end of namespace mgis
36+
37+
#endif /* LIB_MGIS_CONTEXT_IXX */

include/MGIS/LogStream.hxx

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*!
2+
* \file LogStream.hxx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 24/02/2026
6+
*/
7+
8+
#ifndef LIB_MGIS_LOGSTREAM_HXX
9+
#define LIB_MGIS_LOGSTREAM_HXX
10+
11+
#include <iosfwd>
12+
#include <string>
13+
#include <memory>
14+
#include <utility>
15+
#include <string_view>
16+
#include "MGIS/Config.hxx"
17+
18+
namespace mgis {
19+
20+
/*!
21+
* \return the default log stream
22+
*
23+
* \note by default, std::cout is returned
24+
*/
25+
MGIS_EXPORT [[nodiscard]] std::ostream &getDefaultLogStream() noexcept;
26+
/*!
27+
* \brief set the default log stream as a file.
28+
*
29+
* \return a pair whose firt term indicates if the operation was successful.
30+
* In case of failure, the second term contains if an error message.
31+
*
32+
* \param[in] n: file name
33+
* \note In parallel, each process shall have its own output file or call
34+
* `disableDefaultLogStream` except on the root process
35+
*/
36+
MGIS_EXPORT [[nodiscard]] std::pair<bool, std::string> setDefaultLogStream(
37+
std::string_view) noexcept;
38+
/*!
39+
* \brief set the default log stream from an exisiting output stream
40+
*
41+
* \param[in, out] os: output stream
42+
* \note the user is responsible for ensuring that the given object is alive
43+
*/
44+
MGIS_EXPORT void setDefaultLogStream(std::ostream &) noexcept;
45+
/*!
46+
* \brief set the default log stream from an exisiting output stream
47+
*
48+
* \param[in, out] os: output stream
49+
* \note if the given pointer is null, `resetDefaultLogStream` is called
50+
*/
51+
MGIS_EXPORT void setDefaultLogStream(std::shared_ptr<std::ostream>) noexcept;
52+
//! \brief reset the default log stream
53+
MGIS_EXPORT void resetDefaultLogStream() noexcept;
54+
/*!
55+
* \brief disable the default log stream
56+
*
57+
* \note logging is disable by creating a no-op output stream
58+
*/
59+
MGIS_EXPORT void disableDefaultLogStream() noexcept;
60+
/*!
61+
* \brief list of available colors for output stream
62+
* \note this only works on the terminal
63+
*/
64+
enum struct OutputStreamColors {
65+
BLACK,
66+
RED,
67+
GREEN,
68+
YELLOW,
69+
BLUE,
70+
PURPLE,
71+
LIGHTBLUE,
72+
WHITE,
73+
RESET
74+
};
75+
/*!
76+
* \brief change the color of the output for warnings for red
77+
* \param[out] out: output stream
78+
* \param[in] c: color
79+
* \note this only works on the terminal
80+
*/
81+
MGIS_EXPORT bool setStreamColor(std::ostream &,
82+
const OutputStreamColors) noexcept;
83+
/*!
84+
* \brief reset the color of the output
85+
* \param[out] out: output stream
86+
* \param[in] l: verbosity level
87+
*/
88+
MGIS_EXPORT bool resetStreamColor(std::ostream&) noexcept;
89+
/*!
90+
* \brief print a warning message
91+
*
92+
* \tparam Args: types of the arguments
93+
* \param[in] args: streamed object
94+
*/
95+
template <typename... Args>
96+
void warning(std::ostream &, Args &&...) noexcept;
97+
/*!
98+
* \brief print message for debugging
99+
*
100+
* \tparam Args: types of the arguments
101+
* \param[in] args: streamed object
102+
*/
103+
template <typename... Args>
104+
void debug(std::ostream &, Args &&...) noexcept;
105+
106+
} // end of namespace mgis
107+
108+
#include "MGIS/LogStream.ixx"
109+
110+
#endif /* LIB_MGIS_LOGSTREAM_HXX */

include/MGIS/LogStream.ixx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*!
2+
* \file MGIS/LogStream.ixx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 24/02/2026
6+
*/
7+
8+
#ifndef LIB_MGIS_LOGSTREAM_IXX
9+
#define LIB_MGIS_LOGSTREAM_IXX
10+
11+
namespace mgis {
12+
13+
template <typename... Args>
14+
void warning(std::ostream &os, Args &&...args) noexcept {
15+
os << "[warning]: ";
16+
(os << ... << std::forward<Args>(args));
17+
os << std::endl;
18+
} // end of namespace mgis
19+
20+
template <typename... Args>
21+
void debug(std::ostream &os, Args &&...args) noexcept {
22+
os << "[debug]: ";
23+
(os << ... << std::forward<Args>(args));
24+
os << std::endl;
25+
} // end of namespace mgis
26+
27+
} // end of namespace mgis
28+
29+
#endif /* LIB_MGIS_LOGSTREAM_IXX */

src/LogStream.cxx

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*!
2+
* \file LogStream.cxx
3+
* \brief
4+
* \author Thomas Helfer
5+
* \date 24/02/2026
6+
*/
7+
8+
#include <memory>
9+
#include <variant>
10+
#include <fstream>
11+
#include <iostream>
12+
#include "MGIS/LogStream.hxx"
13+
14+
namespace mgis {
15+
16+
[[nodiscard]] static std::
17+
variant<std::monostate, std::ostream *, std::shared_ptr<std::ostream>>
18+
&getGlobalLogStream() noexcept {
19+
static std::variant<std::monostate, std::ostream *,
20+
std::shared_ptr<std::ostream>>
21+
os;
22+
return os;
23+
} // end of getGlobalLogStream
24+
25+
std::ostream &getDefaultLogStream() noexcept {
26+
auto &os = getGlobalLogStream();
27+
if (std::holds_alternative<std::ostream *>(os)) {
28+
auto* const ptr = std::get<std::ostream *>(os);
29+
if (ptr == nullptr) {
30+
return std::cout;
31+
}
32+
return *ptr;
33+
} else if (std::holds_alternative<std::shared_ptr<std::ostream>>(os)) {
34+
auto ptr = std::get<std::shared_ptr<std::ostream>>(os);
35+
if (ptr.get() == nullptr) {
36+
return std::cout;
37+
}
38+
return *ptr;
39+
}
40+
return std::cout;
41+
} // end of getDefaultLogStream
42+
43+
std::pair<bool, std::string> setDefaultLogStream(
44+
std::string_view n) noexcept {
45+
auto ptr = std::make_shared<std::ofstream>(std::string{n});
46+
if (!(*ptr)) {
47+
return {false,
48+
"setDefaultLogStream: can't open file '" + std::string{n} + "'"};
49+
}
50+
setDefaultLogStream(ptr);
51+
return {true, ""};
52+
} // end of setDefaultLogStream
53+
54+
void setDefaultLogStream(std::ostream & os) noexcept{
55+
getGlobalLogStream() = &os;
56+
} // end of setDefaultLogStream
57+
58+
void setDefaultLogStream(std::shared_ptr<std::ostream> ptr) noexcept {
59+
if (ptr.get() == nullptr) {
60+
resetDefaultLogStream();
61+
return;
62+
}
63+
getGlobalLogStream() = ptr;
64+
} // end of setDefaultLogStream
65+
66+
void resetDefaultLogStream() noexcept {
67+
getGlobalLogStream() = std::monostate{};
68+
} // end of resetDefaultLogStream
69+
70+
void disableDefaultLogStream() noexcept {
71+
/*!
72+
* \brief a buffer which allows to create no-op output streams, i.e. streams
73+
* that does not nothing.
74+
*
75+
* see
76+
* https://stackoverflow.com/questions/11826554/standard-no-op-output-stream
77+
* for details
78+
*/
79+
struct NullBuffer : public std::streambuf {
80+
int overflow(int c) override { return c; }
81+
};
82+
static NullBuffer null_buffer;
83+
static std::ostream null_stream(&null_buffer);
84+
setDefaultLogStream(null_stream);
85+
} // end of disableDefaultLogStream
86+
87+
88+
/*!
89+
* \class TerminalColors
90+
* \brief This class contains char sequence corresponding to colors.
91+
* This enables to write ouput messages in color in the terminal.
92+
* \author Thomas Helfer
93+
* \date 26/07/2006
94+
*/
95+
struct TerminalColors {
96+
/*!
97+
* \brief char sequence correponding to black.
98+
* \code
99+
* cout.write(TerminalColors::Black,sizeof(TerminalColors::Black));
100+
* \endcode
101+
*/
102+
static constexpr char Black[5] = {033, '[', '3', '0', 'm'};
103+
/*!
104+
* \brief char sequence correponding to red.
105+
* \code
106+
* cout.write(TerminalColors::Red,sizeof(TerminalColors::Red));
107+
* \endcode
108+
*/
109+
static constexpr char Red[5] = {033, '[', '3', '1', 'm'};
110+
/*!
111+
* \brief char sequence correponding to green.
112+
* \code
113+
* cout.write(TerminalColors::Green,sizeof(TerminalColors::Greeb));
114+
* \endcode
115+
*/
116+
static constexpr char Green[5] = {033, '[', '3', '2', 'm'};
117+
/*!
118+
* \brief char sequence correponding to yellow.
119+
* \code
120+
* cout.write(TerminalColors::Yellow,sizeof(TerminalColors::Yellow));
121+
* \endcode
122+
*/
123+
static constexpr char Yellow[5] = {033, '[', '3', '3', 'm'};
124+
/*!
125+
* \brief char sequence correponding to blue.
126+
* \code
127+
* cout.write(TerminalColors::Blue,sizeof(TerminalColors::Blue));
128+
* \endcode
129+
*/
130+
static constexpr char Blue[5] = {033, '[', '3', '4', 'm'};
131+
/*!
132+
* \brief char sequence correponding to purple.
133+
* \code
134+
* cout.write(TerminalColors::Purple,sizeof(TerminalColors::Purple));
135+
* \endcode
136+
*/
137+
static constexpr char Purple[5] = {033, '[', '3', '5', 'm'};
138+
/*!
139+
* \brief char sequence correponding to light blue.
140+
* \code
141+
* cout.write(TerminalColors::LightBlue,sizeof(TerminalColors::LightBlue));
142+
* \endcode
143+
*/
144+
static constexpr char LightBlue[5] = {033, '[', '3', '6', 'm'};
145+
/*!
146+
* \brief char sequence correponding to white.
147+
* \code
148+
* cout.write(TerminalColors::White,sizeof(TerminalColors::White));
149+
* \endcode
150+
*/
151+
static constexpr char White[5] = {033, '[', '3', '7', 'm'};
152+
/*!
153+
* \brief char sequence correponding to the reset command.
154+
* This causes the terminal to go back to its initial state.
155+
* \code
156+
* cout.write(TerminalColors::Reset,sizeof(TerminalColors::Reset));
157+
* \endcode
158+
*/
159+
static constexpr char Reset[4] = {033, '[', 'm', 017};
160+
};
161+
162+
void setErrorColor(std::ostream &os) noexcept {
163+
os.write(TerminalColors::Red, sizeof(TerminalColors::Red));
164+
}
165+
166+
void setWarningColor(std::ostream &os) noexcept {
167+
os.write(TerminalColors::LightBlue, sizeof(TerminalColors::LightBlue));
168+
}
169+
170+
void resetOutputColor(std::ostream & os) noexcept {
171+
os.write(TerminalColors::Reset, sizeof(TerminalColors::Reset));
172+
}
173+
174+
} // end of namespace mgis

tests/ContextTest.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <vector>
2+
#include <utility>
3+
#include <iostream>
4+
#include <string_view>
5+
#include "MGIS/Context.hxx"
6+
7+
std::optional<std::vector<int>> f() { return std::vector<int>{1, 3, 6}; }
8+
9+
int main() {
10+
using namespace mgis;
11+
auto ctx = Context{};
12+
auto or_raise = ctx.getFailureHandler<>();
13+
auto v = or_raise(f());
14+
std::cout << v[0] << " " << v[1] << " " << v[2] << '\n';
15+
return EXIT_SUCCESS;
16+
}

0 commit comments

Comments
 (0)