- #1
sbrothy
Gold Member
- 556
- 429
- TL;DR Summary
- I was thinking about writing a C++ insights article using the polynomials Baez currently seems fascinated about on his blog. The math isn't really a problem using the GNU Scientific Package. The graphics is doable in OpenGL although I'd prefer Windows DirectX, but I'd prefer not dragging various linux build systems into the picture.
I was thinking about writing a C++ insights article using the polynomials Baez currently seems fascinated about on his blog. The math isn't really a problem using the GNU Scientific Package. The graphics is doable in OpenGL although I'd prefer Windows DirectX, but I'd prefer not dragging various linux build systems into the picture.
Then, to KISS (riiight) I'd only use SPDLOG, GNU Scientific Library and OpenGL. Using no build systems but raw commands to g++ along the lines of:
Some logging *is*s needed and some reading of an XML file might be too. It's like a little project that just keeps getting bigger and bigger!
Also, I'm sure you can see I'm cannibalizing an older project. It might amount to nothing....
Then, to KISS (riiight) I'd only use SPDLOG, GNU Scientific Library and OpenGL. Using no build systems but raw commands to g++ along the lines of:
Code:
#ifndef __PCH_H
#define __PCH_H
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Precompiled header. Libraries and generically useful inline functions shared across programs and modules.
/*
g++ -H -v -std=c++17 -Wall -Wextra -fmax-errors=3 -O3 -fdiagnostics-color=always -x c++-header -c pch.h -o pch.h.gch
*/
// Include on GCC command line using the "-include" option as in "-include pch.h".
//
// sbrothy@gmail.com 2022
//
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CPPVER17 201703L
#if !defined(__GNUC__) || !defined(__cplusplus) || (__cplusplus < CPPVER17)
#error Target platform is Linux, C++ 17 or higher.
#endif
// c++
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <stdexcept>
// boost
//#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/tokenizer.hpp>
#include <boost/regex.hpp>
// GNU scientific library
#include <gsl/gsl_poly.h>
// opengl
#include <GL/glut.h>
//#include <boost/format.hpp>
//#include <boost/foreach.hpp>
//#include <boost/algorithm/string.hpp>
//#include <boost/token_functions.hpp>
//#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
//#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
//#include <boost/property_tree/ptree.hpp>
//#include <boost/property_tree/xml_parser.hpp>
//#endif
//#include <boost/property_tree/json_parser.hpp>
//#include <boost/thread/mutex.hpp>
//#include <boost/asio.hpp>
//#include <boost/asio/error.hpp>
//#include <boost/asio/ssl.hpp>
//#include <boost/beast/core.hpp>
//#include <boost/beast/http.hpp>
//#include <boost/asio/strand.hpp>
//#include <boost/beast/http/status.hpp>
//#include <boost/beast/version.hpp>
//#include <boost/algorithm/string/split.hpp>
// spdlog
#define MY_SPDLOG
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
#define SPDLOG_FUNCTION _PRETTY_FUNCTION_
#include <spdlog/spdlog.h>
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>
namespace pch {
/*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// hack to determine exception type
auto const ex_type = [] -> const char * {
return abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), 0, 0, new int);
}
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
inline void slurp_file(const std::string fname, std::string &data)
{
std::ifstream ifs;
ifs.exceptions (std::ifstream::badbit | std::ifstream::eofbit | std::ifstream::failbit );
ifs.open(fname);
std::ostringstream oss;
oss << ifs.rdbuf();
ifs.close();
data = oss.str();
}
#ifdef SPDLOG_H
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
inline std::shared_ptr<spdlog::async_logger> init_spdlog(
std::string logger_name,
std::string logfile,
bool log_to_console = false,
spdlog::level::level_enum log_level = spdlog::level::trace,
spdlog::level::level_enum flush_level = spdlog::level::trace,
std::string pattern = "[%n][%@][%P][%t][%a:%d:%m:%Y][%H:%M:%S:%e:%f][%^%l%$]: %v"
)
{
spdlog::init_thread_pool(8192, 1);
std::vector<spdlog::sink_ptr> sinks;
if(log_to_console) {
sinks.push_back( std::make_shared<spdlog::sinks::stdout_color_sink_mt>() );
}
sinks.push_back( std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logfile, 1024 * 1024 * 5, 3, true));
auto log = std::make_shared<spdlog::async_logger>(logger_name, sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
log->flush_on(flush_level);
log->set_level(log_level);
log->set_pattern(pattern);
spdlog::register_logger(log);
spdlog::set_default_logger(log);
spdlog::info("\r\n\r\n\
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n\
SPDLOG header only logging API initialized for asynchronous use. The EOL character\r\n\
has been removed so each call to a log function must be manually \"newlined\" as in :\r\n\r\n\
log->trace(\"blah\\r\\n\");\r\n\r\n\
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n\r\n");
spdlog::info("logger id: \"{}\". Rotating logfile name: \"{}\".\r\n", logger_name, logfile);
spdlog::trace("Trace entry.\r\n");
spdlog::debug("Debug entry.\r\n");
spdlog::info("Information entry.\r\n");
spdlog::warn("Warning entry.\r\n");
spdlog::error("Error entry.\r\n");
spdlog::critical("Critical entry.\r\n");
spdlog::info("Done.\r\n");
return log;
}
#endif // SPDLOG_H
}; // namespace pch {
#endif // __PCH_H
Code:
/*
g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -c -o main.o -include pch.h main.cpp
g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -o main main.o -L/usr/lib/x86_64-linux-gnu/cmake -lboost_regex -lfmt -lgsl -lglut -lGL -lGLU
*/
std::shared_ptr<spdlog::async_logger> g_log = nullptr;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void glExceptOnError(const std::string &func)
{
const GLenum code = glGetError();
const std::string err_msg = reinterpret_cast<const char*>(gluErrorString(code));
switch(code) {
case GL_NO_ERROR:
spdlog::trace("{}: {}\n", func, err_msg);
break;
case GL_INVALID_ENUM:
case GL_INVALID_VALUE:
case GL_INVALID_OPERATION:
case GL_INVALID_FRAMEBUFFER_OPERATION:
case GL_OUT_OF_MEMORY:
case GL_STACK_UNDERFLOW:
case GL_STACK_OVERFLOW:
spdlog::error("{}: {}\n", func, err_msg);
throw std::runtime_error(func + ": " + err_msg);
};
}
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(-0.5f, -0.5f); // x, y
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
glFlush(); // Render now
}
int main(int argc, char **argv)
{
const std::string log_name = argv[0];
const std::string log_file = "./" + log_name + ".log";
g_log = pch::init_spdlog(log_name, log_file);
#ifndef NDEBUG
std::ostringstream deb;
deb << "[argc=" << argc << ']';
for(int n = 0; n < argc; n++)
deb << "\n[argv[" << n << "]=" << argv[n] << ']';
spdlog::trace("int main({}, {})\n >>\n", argc, deb.str());
#endif
glutInit(&argc, argv);
glExceptOnError("glutInit");
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glExceptOnError("glutInitDisplayMode");
glutCreateWindow("Baez Polynomial fun"); // Create a window with the given title
glExceptOnError("glutCreateWindow");
glutFullScreen();
glExceptOnError("glutFullScreen");
glutDisplayFunc(display); // Register display callback handler for window re-paint
glExceptOnError("glutDisplayFunc");
glutMainLoop();
glExceptOnError("glutMainLoop");
// glClear(GL_COLOR_BUFFER_BIT);
// glMatrixMode(GL_PROJECTION);
// glLoadIdentity();
// gluOrtho2D( 0.0, 500.0, 500.0,0.0 );
// glutInitWindowSize(320, 320); // Set the window's initial width & height
// glutMainLoop();
/*
int i;
// coefficients of P(x) = -1 + x^5
double a[6] = { -1, 0, 0, 0, 0, 1 };
double z[10];
gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc(6);
gsl_poly_complex_solve(a, 6, w, z);
gsl_poly_complex_workspace_free(w);
std::ostringstream oss;
for(i = 0; i < 5; i++) {
oss << std::resetiosflags(std::ios_base::fmtflags(0));
oss << 'z' << std::setw(10) << i;
oss << " = " << std::fixed << std::setprecision(18) << std::showpos << std::setw(20) << z[2*i] << ' ' << z[2*i+1] << std::endl;
}
std::string res = oss.str();
spdlog::info("\n{}\n", res);
std::cout << res << std::endl;
*/
spdlog::trace("{} main(void) <<\n", EXIT_SUCCESS);
return EXIT_SUCCESS;
}
Some logging *is*s needed and some reading of an XML file might be too. It's like a little project that just keeps getting bigger and bigger!
Also, I'm sure you can see I'm cannibalizing an older project. It might amount to nothing....