-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathout.h
167 lines (124 loc) · 4.94 KB
/
out.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#pragma once
/*
out.h - Helper class for file reporting
NB: TriangulateOBJ.h has no dependencies to this file, only main.cpp is using it.
This header provides a set of utility functions for handling file operations,
reporting file sizes and execution times, and working with file paths.
Copyright (c) 2023 FalconCoding
This software is released under the terms of the
GNU General Public License v3.0. Details and terms of this
license can be found at: https://www.gnu.org/licenses/gpl-3.0.html
*/
#include <string>
#include <chrono>
#include <sstream>
#include <iostream>
#include "cmd.h"
#include "div.h"
#include "TriangulateOBJ.h"
#define indent std::string(5, ' ')
using Clock = std::chrono::high_resolution_clock;
static std::chrono::time_point<Clock> init;
std::string stopwatch();
std::string file_size_info();
inline void report(const obj::Triangulate& obj)
{
constexpr int n(60);
if( obj.metrics().empty() ) return;
const auto v = obj.metrics().vertices;
const auto t = obj.metrics().triangles;
const auto p = obj.metrics().polygons;
coutLocaleGuard localeGuard(std::locale(std::locale(), new thousandsFacet));
std::cout << indent << std::endl << std::endl;
std::cout << indent << std::string(n, '-') << std::endl;
std::cout << indent << target.filename().string() << " " << file_size_info() << std::endl;
std::cout << indent << std::string(n, '-') << std::endl;
std::cout << indent << "Vertices : " << std::setw(10) << v << std::endl;
std::cout << indent << std::string(n, '-') << std::endl;
std::cout << indent << "Triangles : " << std::setw(10) << t.first << std::endl;
std::cout << indent << "Polygons : " << std::setw(10) << p.first << std::endl;
std::cout << indent << std::string(n, '-') << std::endl;
std::cout << indent << "Triangles (after) : " << std::setw(10) << t.first + t.second << " (+" << t.second << ")" << std::endl;
std::cout << indent << "Polygons (after) : " << std::setw(10) << p.first - p.second << std::endl;
std::cout << indent << std::string(n, '-') << std::endl;
std::cout << indent << "Execution time : " << stopwatch() << std::endl;
std::cout << indent << std::string(n, '-') << std::endl << std::endl;
}
inline std::string stopwatch(const std::chrono::time_point<Clock>& time, const std::chrono::time_point<Clock>& stop)
{
using Seconds = std::chrono::seconds;
using Minutes = std::chrono::minutes;
using Hours = std::chrono::hours;
using MilliSeconds = std::chrono::milliseconds;
using MicroSeconds = std::chrono::microseconds;
const auto duration = std::chrono::duration_cast<MicroSeconds>(stop - time);
const auto hours = std::chrono::duration_cast<Hours>(duration);
const auto minutes = std::chrono::duration_cast<Minutes>(duration % Hours(1));
const auto seconds = std::chrono::duration_cast<Seconds>(duration % Minutes(1));
const auto milliseconds = std::chrono::duration_cast<MilliSeconds>(duration % Seconds(1));
const auto microseconds = std::chrono::duration_cast<MicroSeconds>(duration % MilliSeconds(1));
std::string result;
if( minutes.count() > 0 )
{
result += (hours.count() < 10 ? "0" : "") + std::to_string(hours.count()) + ":";
result += (minutes.count() < 10 ? "0" : "") + std::to_string(minutes.count()) + ":";
result += (seconds.count() < 10 ? "0" : "") + std::to_string(seconds.count());
}
else if( seconds.count() > 0 )
result += std::to_string(seconds.count()) + " seconds ";
else if( milliseconds.count() > 0 )
result += std::to_string(milliseconds.count()) + " milliseconds ";
else
result += std::to_string(microseconds.count()) + " microseconds";
return result;
}
inline void launch()
{
init = Clock::now();
}
inline std::string stopwatch()
{
return stopwatch(init, Clock::now());
}
inline std::string byte_text(const size_t&);
inline std::string file_size()
{
struct stat st;
if( stat(target.string().c_str(), &st) != 0 )
return {};
return byte_text(static_cast<size_t>(st.st_size));
}
inline std::string file_extend()
{
struct stat stSource;
if( stat(source.string().c_str(), &stSource) != 0 )
return {};
struct stat stTarget;
if( stat(target.string().c_str(), &stTarget) != 0 )
return {};
const auto byteSource = static_cast<size_t>(stSource.st_size);
const auto byteTarget = static_cast<size_t>(stTarget.st_size);
if( byteSource == byteTarget )
return {};
if( byteSource < byteTarget )
return "+" + byte_text(byteTarget - byteSource);
return "-" + byte_text(byteSource - byteTarget);
}
inline std::string file_size_info()
{
return file_size() + " (" + file_extend() + ")";
}
inline std::string byte_text(const size_t& byte)
{
const char* sizeUnits[] = {" bytes" , "KB" , "MB" , "GB" , "TB"};
auto unitIndex = 0;
auto size = static_cast<double>(byte);
while( size >= 1024.0 && unitIndex < 4 )
{
size /= 1024.0;
unitIndex++;
}
std::ostringstream result;
result << std::fixed << std::setprecision(0) << size << sizeUnits[unitIndex];
return result.str();
}