CppQuickStart/utils.hpp

93 lines
3.3 KiB
C++
Raw Normal View History

2019-03-28 16:38:50 +01:00
#ifndef DEF_utils
#define DEF_utils
#include <ostream>
2019-03-30 11:48:51 +01:00
#include <utility>
2019-03-28 16:38:50 +01:00
#define PRINT_VAR(x) std::cout << #x << "\t= " << (x) << "\n"
#define PRINT_VEC(x); {std::cout << #x << "\t= "; \
for(unsigned int i_print_vec = 0 ; i_print_vec < (x).size() ; i_print_vec++) \
std::cout << (x)[i_print_vec] << "\t"; \
std::cout << "\n";}
2019-03-30 11:48:51 +01:00
#define PRINT_STR(x) std::cout << (x) << "\n"
template<typename T, typename T2> auto min(const T & a, const T2 & b) -> decltype(a | b) { return (a < b) ? T(a) : T(b); }
template<typename T, typename T2> auto max(const T & a, const T2 & b) -> decltype(a | b) { return (a < b) ? T(b) : T(a); }
2019-03-28 16:38:50 +01:00
/// To be sure that floating point numbers won't be casted to integers in ::abs()...
template<typename T> T sureAbs(const T & x) { return (x < T(0)) ? -x : x; }
2019-04-24 12:13:56 +02:00
//*
/// Generic operator<< for ostream, (to print std::vector, etd::list, std::map, etc). Can generate conflicts with specialized operator<< overloads.
2019-03-28 16:38:50 +01:00
template<typename T, template<class,class...> class C, class... Args>
std::ostream& operator<<(std::ostream& os, const C<T,Args...>& objs)
{
for (auto const& obj : objs)
os << obj << ' ';
return os;
2019-04-24 12:13:56 +02:00
}//*/
/// define UTILS_NO_CHRONO to deactivate chronometer
#ifndef UTILS_NO_CHRONO
#include <iostream>
#include <chrono>
#include <ratio>
#include <ctime>
2019-03-28 16:38:50 +01:00
2019-04-24 12:13:56 +02:00
/// Convenience macro to create a Chronometer object that will measure the execution time of its scope.
#define TIMER(str) Chronometer __chrono((str))
/// \class Chronometer class. Used to measure the execution time of its scope.
///
/// Usage :
///
/// {
/// TIMER("My timer");
/// /* some code to be profiled */
/// }// <--- the chronometer measures the time between the call to its constructor and the call to its destructor.
///
/// Possible output :
///
/// My timer : 0.12317568 s (+/- 1e-09 s)
///
template<int T=1>
struct Chronometer
2019-03-30 11:48:51 +01:00
{
2019-04-24 12:13:56 +02:00
std::string name;
std::chrono::high_resolution_clock::time_point t0;
/// Creates the Chronometer object with the provided name and stores the time.
Chronometer(const std::string & name_ = "")
: name(name_),
t0(std::chrono::high_resolution_clock::now())
{}
/// Measures the time elapsed between the creation of the object and its destruction, and prints the result in std::cout.
~Chronometer() { MeasureTimeElapsed(); }
/// Resets the timer. Allows the measurement of the execution time of several sub-intervals in the current scope.
void Reset() { t0 = std::chrono::high_resolution_clock::now(); }
/// Measures the time elapsed between the creation of the object and its destruction, and prints the result in std::cout.
void MeasureTimeElapsed()
{
// measure time since object creation
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t1 - t0);
// clock resolution
auto resolution_ratio = std::chrono::high_resolution_clock::period();
double resolution = double(resolution_ratio.num)/resolution_ratio.den;
std::cout.precision(16);
std::cout << name.c_str() << "\t: " << time_span.count() << " s (+/- " << resolution << " s)" << std::endl;// use of c_str() so that there is no ambiguity with the generic operator<<
}
2019-03-30 11:48:51 +01:00
};
2019-04-24 12:13:56 +02:00
#else// chronometer
#define TIMER(str)
#endif// chronometer
2019-03-28 16:38:50 +01:00
#endif