28 #ifndef TOMOGRAPHER_TOOLS_FMT_H 29 #define TOMOGRAPHER_TOOLS_FMT_H 76 const char * what()
const throw() {
98 char * buffer =
new char[size];
101 int nsize =
vsnprintf(buffer, size, fmt, ap1);
110 buffer =
new char[size];
111 nsize =
vsnprintf(buffer, size, fmt, vl);
149 #define streamstr(tokens) \ 150 dynamic_cast<std::ostringstream&>( \ 151 std::ostringstream().seekp(0) << tokens \ 161 #define streamcstr(tokens) streamstr(tokens).c_str() 169 namespace tomo_internal {
172 template<
typename T>
static auto test_has_stream_op(
int)
173 ->
typename sfinae_yes<decltype(*((std::ostream*)(NULL)) << *((T*)(NULL)))>::yes&;
174 template<
typename T>
static auto test_has_stream_op(
long)
175 ->
typename sfinae_no<>::no&;
200 static constexpr
bool value = (
sizeof(tomo_internal::test_has_stream_op<T>(0))
201 ==
sizeof(
typename tomo_internal::sfinae_yes<>::yes));
205 namespace tomo_internal {
207 template<
typename T_>
208 struct StreamIfPossibleWrapper
215 StreamIfPossibleWrapper(
221 : obj(obj_), before(before_), after(after_), alternative(alternative_)
239 void stream_into(OStream&& stream)
const 241 stream << alternative;
245 void stream_into(OStream&& stream)
const 247 stream << before << obj << after;
252 inline std::ostream & operator<<(std::ostream & stream, const StreamIfPossibleWrapper<T>& wobj)
254 wobj.stream_into(stream);
259 inline std::ostream&& operator<<(std::ostream&& stream, const StreamIfPossibleWrapper<T>& wobj)
261 wobj.stream_into(stream);
268 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN 281 inline tomo_internal::StreamIfPossibleWrapper<T>
286 return tomo_internal::StreamIfPossibleWrapper<T>(obj,
std::move(before),
374 double dt_f =
std::modf(seconds, &dt_i_d);
375 int dt_i = (int)(dt_i_d+0.5);
377 return fmts(
"%d:%02d:%02d.%03d", dt_i/3600, (dt_i/60)%60, dt_i%60, (
int)(dt_f*1000+0.5));
389 template<
typename Rep,
typename Period>
395 double seconds = (double)dt.
count() * Duration::period::num / Duration::period::den ;
433 if (x.
size() > columns()) {
450 if (x.
size() > columns()) {
465 if (x.
size() > columns()) {
487 namespace tomo_internal {
488 class LazyOStreamCallback {
490 template<
typename CallFn>
491 LazyOStreamCallback(CallFn && fn_) : fn(fn_) { }
513 int first_indent_ = 0,
514 bool hard_wrap_long_lines_ =
false,
515 bool obey_newlines_ =
false)
519 first_indent(first_indent_),
520 hard_wrap_long_lines(hard_wrap_long_lines_),
521 obey_newlines(obey_newlines_)
531 int startline_len = first_indent + (int)init.
size();
533 auto finish_line = [&output,&startline,&startline_len,
this](
std::string linetoend =
"") {
535 if (full_line.
size()) {
539 startline_len = indent;
541 auto add_startline = [&startline,&startline_len](
std::string morestartline) {
543 startline_len += morestartline.size();
546 while (pos < text.
size()) {
552 if (text[pos] ==
' ' || text[pos] ==
'\n') {
553 bool new_paragraph =
false;
554 while (pos < text.
size() && (text[pos] ==
' ' || text[pos] ==
'\n')) {
555 if (text[pos] ==
'\n') {
556 new_paragraph =
true;
568 if (nxtpos != std::string::npos && nxtpos < pos+this_w) {
571 finish_line( text.
substr(pos, nxtpos-pos) );
576 add_startline( text.
substr(pos, nxtpos-pos) );
582 if (text.
size() < pos + this_w) {
584 finish_line( text.
substr(pos) );
591 if (lpos == std::string::npos || lpos < pos) {
593 if (hard_wrap_long_lines) {
594 finish_line( text.
substr(pos, this_w) );
600 if (nxtpos == std::string::npos) {
602 finish_line( text.
substr(pos) );
607 finish_line( text.
substr(pos, nxtpos-pos) );
612 finish_line( text.
substr(pos, lpos-pos) );
627 tomo_internal::LazyOStreamCallback wrapped(
const std::string & text)
const 630 return tomo_internal::LazyOStreamCallback([lines,
this](
std::ostream & stream) {
643 int getIndent()
const {
return indent; }
644 int getFirstIndent()
const {
return first_indent; }
645 bool getHardWrapLongLines()
const {
return hard_wrap_long_lines; }
646 bool getObeyNewlines()
const {
return obey_newlines; }
653 bool hard_wrap_long_lines;
676 tomo_internal::LazyOStreamCallback addFootNote(
std::string footnote)
678 return tomo_internal::LazyOStreamCallback([footnote,
this](
std::ostream & stream) {
690 &&
"Your footnotes have changed numbering! Check your silent footnotes.") ;
697 tomo_internal::LazyOStreamCallback wrapped(
std::size_t width = 80)
const 699 return tomo_internal::LazyOStreamCallback([width,
this](
std::ostream & stream) {
705 stream << wrapper.wrapped(ftlist[k]);
720 size_t start_pos = 0;
721 while (s.
size() && (start_pos = s.
find(
"\n", start_pos)) != std::string::npos) {
722 s.
replace(start_pos, 1, nlindent);
723 start_pos += nlindent.
length();
727 stream <<
" [" <<
std::setw(w) << (k+1) <<
"] " << s <<
"\n";
Base namespace for the Tomographer project.
T find_last_of(T... args)
T find_first_of(T... args)
Some C++ utilities, with a tad of C++11 tricks.
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
#define tomographer_assert(...)
Assertion test macro.