25 #include "valuevar.hpp"
36 string to_string(
const std::shared_ptr<VClos>& v,
const cfg::CfgMap& cfg);
39 string to_string(
const std::shared_ptr<VBuiltinG>& v,
const cfg::CfgMap& cfg);
40 string to_string(
const SpFuture& v,
const cfg::CfgMap& cfg);
43 string to_string(
const SpTimer& v,
const cfg::CfgMap& cfg);
50 string to_string(Global::dtime dt,
const cfg::CfgMap& cfg,
bool unquoted=
false);
51 string to_string(Global::dtime::duration d,
const cfg::CfgMap& cfg);
54 string to_string(
const string& s,
const cfg::CfgMap& cfg,
bool unquoted=
false);
55 string to_string(
const val::integer_t& s,
const cfg::CfgMap& cfg);
56 string to_string(
const val::SpVI& s,
const cfg::CfgMap& cfg);
61 using namespace std::string_literals;
70 transform(v.begin(), v.end(), back_inserter(res),
71 [cfg](
const T& t) {
return to_string(t, cfg); });
115 const string& prefix=
"",
116 const string& postfix=
"") {
117 if (a.
names.size() > d && a.hasNames(d)) {
121 for (idx_type j=0; j<n; ++j) {
122 vs.push_back(
"[" + prefix + std::to_string(j+1) + postfix +
"]");
128 inline Vector<zstring> getVectorLineNumbers(idx_type n, idx_type ncols) {
130 auto nrows = n / ncols;
134 for (idx_type j=0; j<nrows; ++j) {
135 vs.push_back(
"[" + std::to_string(1 + j*ncols) +
"]");
141 auto vl = vector<unsigned>();
142 transform(vs.begin(), vs.end(), back_inserter(vl), [](
string s){
return s.length(); });
148 unsigned cfgWidth =
static_cast<size_t>(get<int64_t>(cfg.get(
"width")));
149 auto cfgMaxPrint =
static_cast<arr::idx_type
>(get<int64_t>(cfg.get(
"max.print")));
151 auto a = a_p.
size() > cfgMaxPrint ? a_p.
subsetRows(cfgMaxPrint) : a_p;
154 idx_type n = min(a.dim[0], cfgMaxPrint);
155 auto vs = vectorToString(*a.v[0], cfg);
157 auto lenValues = getLengths(vs);
159 auto colstring = a.hasNames(0) ? getDimnames(a, 0, n) :
Vector<
zstring>();
162 auto lenNames = getLengths(colstring);
163 colWidth = std::max(*max_element(lenNames.begin(), lenNames.end()),
164 *max_element(lenValues.begin(), lenValues.end())) + 1;
166 colWidth = *max_element(lenValues.begin(), lenValues.end()) + 1;
170 auto ncols = min(cfgWidth / colWidth,
static_cast<unsigned>(n));
172 auto vln = getVectorLineNumbers(n, ncols);
173 auto lenVln = getLengths(vln);
174 auto vlnWidth = *max_element(lenVln.begin(), lenVln.end());
175 while (ncols > 1 && vlnWidth + ncols*colWidth > cfgWidth) {
177 vln = getVectorLineNumbers(n, ncols);
178 lenVln = getLengths(vln);
179 vlnWidth = *max_element(lenVln.begin(), lenVln.end());
181 auto nrows = n / ncols;
182 if (n % ncols) ++nrows;
183 for (
unsigned j=0; j<nrows; ++j) {
188 for (
unsigned k=0; k<ncols; ++k) {
190 if (k+1 + j*ncols < n) {
191 ss.width(colWidth-1);
192 ss << left << colstring[k + j*ncols];
195 ss << left << colstring[k + j*ncols];
203 ss << right << vln[j];
204 for (
unsigned k=0; k<ncols; ++k) {
206 if (k+1 + j*ncols < n) {
207 ss.width(colWidth-1);
208 ss << left << vs[k + j*ncols];
211 ss << left << vs[k + j*ncols];
215 if (j<nrows-1) ss << endl;
219 if (n < a_p.dim[0]) {
220 ss << endl <<
" [ reached getOption(""max.print"") -- omitted " <<
221 a_p.dim[0] - n <<
" entries ]";
229 const idx_type MAXIDX = std::numeric_limits<idx_type>::max();
232 if (dim.size() < 2) {
233 throw std::out_of_range(
"getFirstVIndex(): dim.size() < 2");
235 if (maxrows < dim[0]) {
237 std::iota(v.begin(), v.end(), 0);
244 for (idx_type j=2; j<dim.size(); ++j) {
251 if (dim.size() < 2) {
252 throw std::out_of_range(
"getNextVIndex(): dim.size() < 2");
254 if (i.size() != dim.size()) {
255 throw std::out_of_range(
"getNextVIndex(): index and dim sizes mismatch");
257 for (idx_type j=dim.size()-1; j>=2; --j) {
258 if (get<IntIndex>(i[j].idx).vi[0] == MAXIDX) {
260 }
else if (get<IntIndex>(i[j].idx).vi[0] + 1 >= dim[j]) {
261 auto& ref = get<IntIndex>(i[j].idx);
262 arr::setv(ref.vi, 0, 0UL);
264 auto& ref = get<IntIndex>(i[j].idx);
265 arr::setv(ref.vi, 0, (ref.vi)[0]+1);
272 inline string displaySliceHeader(
const vector<Index>& ii,
const vector<unique_ptr<Dname>>& names) {
275 throw std::out_of_range(
"displaySliceHeader(): ii.size() < 3");
278 for (idx_type j=2; j<ii.size(); ++j) {
279 auto idx = get<IntIndex>(ii[j].idx).vi[0];
280 if (j < names.size()) {
281 ss <<
", " << (idx == MAXIDX ?
"0" :
282 (names[j]->size() ? (*names[j])[idx] : std::to_string(idx+1)));
289 template<
typename T,
typename R>
290 string displaySlice(
const Array<T>& slice,
295 auto cfgWidth =
static_cast<size_t>(get<int64_t>(cfg.get(
"width")));
299 auto nrows = min(nleft / std::max(slice.dim[1],
static_cast<idx_type
>(1)), slice.dim[0]);
301 if (rownames_c.size() == 0) {
302 for (idx_type j=0; j<nrows; ++j) {
303 arr::setv(rownames, j,
arr::zstring(
"[" + std::to_string(j+1) +
",]"));
306 for (idx_type j=0; j<nrows; ++j) {
307 arr::setv(rownames, j,
arr::zstring(to_string(rownames_c[j], cfg,
true)));
311 auto lenRownames = getLengths(rownames);
312 auto colnames = getDimnames(slice, 1, min(nleft, slice.dim[1]),
",");
313 auto lenColnames = getLengths(colnames);
314 auto data = arrayToString(slice, cfg);
315 auto lenData = applyf<arr::zstring, unsigned>(data, [](
const arr::zstring& s){
return s.length(); });
316 auto colWidths = maxcol(lenData);
317 for (idx_type j=0; j<lenColnames.size(); ++j) {
318 arr::setv(colWidths, j, std::max(colWidths[j], lenColnames[j]));
320 colWidths = applyf<unsigned, unsigned>(colWidths, [](
unsigned u) {
return ++u; });
321 auto rownamesWidth = lenRownames.size() ?
322 *max_element(lenRownames.begin(), lenRownames.end()) : 0;
324 idx_type colStart = 0;
325 while (colStart < colnames.size()) {
327 idx_type colEnd = colStart + 1;
328 unsigned nchar = rownamesWidth + colWidths[colEnd-1];
329 while (colEnd < colnames.size()) {
330 nchar += colWidths[colEnd];
331 if (nchar > cfgWidth) {
338 ss.width(rownamesWidth);
340 for (idx_type col=colStart; col<colEnd; ++col) {
341 ss.width(colWidths[col]);
345 if (colEnd == colnames.size() && colEnd < slice.dim[1]) {
350 for (idx_type row=0; row<rownames.size(); ++row) {
351 ss.width(rownamesWidth);
352 ss << (rownames_c.size() ? left : right) << rownames[row] << right;
353 for (idx_type col=colStart; col<colEnd; ++col) {
355 ss.width(colWidths[col]-1);
356 ss << left << data[row + col * slice.dim[0]] << right;
363 nleft -= nrows * std::max(slice.dim[1],
static_cast<idx_type
>(1));
364 return ss.str().substr(0, ss.str().length()-1);
371 string displaySliceWithZeros(
const vector<Index>& i,
373 const vector<unique_ptr<Dname>>& names,
380 auto nrows = min(nleft / std::max(dim[1],
static_cast<idx_type
>(1)), dim[0]);
382 if (rownames_c.size() == 0) {
383 for (idx_type j=0; j<nrows; ++j) {
384 arr::setv(rownames, j,
arr::zstring(
"[" + std::to_string(j+1) +
",]"));
387 for (idx_type j=0; j<nrows; ++j) {
388 arr::setv(rownames, j,
arr::zstring(to_string(rownames_c[j], cfg,
true)));
391 auto lenRownames = getLengths(rownames);
392 auto rownamesWidth = lenRownames.size() ?
393 *max_element(lenRownames.begin(), lenRownames.end()) : 0;
395 auto ncols = min(nleft, std::max(dim[1],
static_cast<idx_type
>(1)));
396 auto colnames = names[1]->names;
397 if (colnames.size() == 0) {
398 for (idx_type j=0; j<ncols; ++j) {
399 colnames.push_back(
"[," + std::to_string(j+1) +
"]");
402 colnames.resize(ncols);
404 auto lenColnames = getLengths(colnames);
405 auto colnamesWidth = lenColnames;
406 for_each(colnamesWidth.begin(), colnamesWidth.end(), [](
unsigned& x) { ++x; });
408 idx_type colStart = 0;
409 auto cfgWidth =
static_cast<size_t>(get<int64_t>(cfg.get(
"width")));
410 while (colStart < colnames.size()) {
412 idx_type colEnd = colStart + 1;
413 unsigned nchar = rownamesWidth + lenColnames[colEnd-1];
414 while (colEnd < colnames.size()) {
415 nchar += colnamesWidth[colEnd];
416 if (nchar > cfgWidth) {
424 ss.width(rownamesWidth);
426 for (idx_type col=colStart; col<colEnd; ++col) {
427 ss.width(colnamesWidth[col]);
431 if (colEnd == colnames.size() && colEnd < dim[1]) {
437 for (idx_type row=0; row<rownames.size(); ++row) {
438 ss.width(rownamesWidth);
439 ss << (rownames_c.size() ? left : right) << rownames[row] << right;
445 nleft -= nrows * ncols;
447 return ss.str().substr(0, ss.str().length()-1);
451 template<
typename T,
typename R>
456 auto cfgMaxPrint =
static_cast<size_t>(get<int64_t>(cfg.get(
"max.print")));
461 throw domain_error(
"array with no dimensions");
465 if (all_of(a.dim.begin(), a.dim.end(), [](idx_type x) { return x==0; })) {
466 ss << arr::TypeName<T>::s <<
'(';
467 copy(a.dim.begin(), a.dim.end() - 1, ostream_iterator<idx_type>(ss,
"x"));
475 if (a.dim.size() == 1) {
476 return displayVector(a, cfg);
482 bool hasZeros = std::any_of(a.dim.begin(), a.dim.end(), [](idx_type x) { return x==0; });
489 for_each(dim1.begin(), dim1.end(), [](idx_type& x) { if (!x) x = 1; });
492 idx_type totslices, nslices, ommittedSlices;
493 idx_type sliceSize = dim1[0] * dim1[1];
494 idx_type tot = accumulate(dim1.begin(), dim1.end(), 1, std::multiplies<idx_type>());
495 if (a.dim.size() == 2) {
496 totslices = nslices = 1;
499 totslices = accumulate(dim1.begin()+2, dim1.end(), 1, std::multiplies<idx_type>());
500 nslices = min(totslices, cfgMaxPrint / sliceSize);
501 if (min(tot,
static_cast<idx_type
>(cfgMaxPrint)) % sliceSize) {
504 ommittedSlices = totslices - nslices;
507 auto nleft = min(tot, left);
508 idx_type ommittedRows = tot <= left ? 0 : (dim1[0] - nleft % sliceSize / dim1[1]);
509 if (cfgMaxPrint >= dim1[1]) {
510 ommittedRows %= dim1[0];
513 idx_type maxrows = min(dim1[0], nleft / dim1[1]);
514 auto vi = getFirstVIndex(a.dim, maxrows);
515 for (idx_type k=0; k<nslices; ++k) {
517 ss << displaySliceHeader(vi, a.
names) << endl;
520 ss << displaySliceWithZeros(vi, a.dim, a.
names, rownames, cfg, nleft) << endl;
524 auto slice = a(vi,
false);
525 ss << displaySlice(slice, rownames, cfg, nleft) << endl;
530 getNextVIndex(vi, dim1);
532 left = tot < left ? left - tot : 0;
536 if (ommittedRows && ommittedSlices) {
537 ss <<
" [ reached getOption(""max.print"") -- omitted "
538 << ommittedRows <<
" row(s) and " << ommittedSlices <<
" slice(s) ]" << endl;
539 }
else if (ommittedRows) {
540 ss <<
" [ reached getOption(""max.print"") -- omitted "
541 << ommittedRows <<
" row(s) ]" << endl;
542 }
else if (ommittedSlices) {
543 ss <<
" [ reached getOption(""max.print"") -- omitted "
544 << ommittedSlices <<
" slice(s) ]" << endl;
547 return ss.str().substr(0, ss.str().length()-1);
551 string display(
const SpVList& l,
const cfg::CfgMap& cfg,
string prefix,
size_t& left);
555 size_t left =
static_cast<arr::idx_type
>(get<int64_t>(cfg.get(
"max.print")));
556 return display(v, v.
names[0]->names, cfg, left);
562 size_t left =
static_cast<arr::idx_type
>(get<int64_t>(cfg.get(
"max.print")));
563 return display(*v, v->names[0]->names, cfg, left);
570 typedef string result_type;
572 template <
typename T>
573 string operator()(
const T& t,
const cfg::CfgMap& cfg)
const {
574 return to_string(t, cfg);
578 inline string to_string(
const val::Value& v,
const cfg::CfgMap& cfg=cfg::cfgmap) {
582 string display(
const val::Value& v);
585 string str(
const val::Value& v,
const cfg::CfgMap& cfg, std::string prefix=
"");
588 template <
typename T>
589 string str(
const T& v,
const cfg::CfgMap& cfg, std::string prefix) {
590 auto cfgWidth =
static_cast<size_t>(get<int64_t>(cfg.get(
"width")));
600 for (arr::idx_type i=0; i<v.getdim().size(); ++i) {
602 dims <<
"1:" << v.getdim(i);
603 if (i != v.getdim().size()-1) {
606 if (ss.str().size() + dims.str().size() > cfgWidth-4) {
618 for (arr::idx_type i=0; i<v.size(); ++i) {
620 elt << to_string(v[i], cfg);
621 if (ss.str().size() + elt.str().size() > cfgWidth-4) {
627 if (i != v.size()-1) ss <<
' ';
632 bool hasDimNames =
false;
633 auto dimnames = make_cow<val::VList>(
false);
634 for (arr::idx_type i=0; i<v.getdim().size(); ++i) {
636 auto dimarray = make_cow<val::VArrayS>(
false,
638 v.getNames(i).names);
639 dimnames->push_back(std::make_pair(
arr::zstring(
""), val::Value(dimarray)));
647 ss << std::endl << prefix <<
" - dimnames =" << str(val::Value(dimnames), cfg, prefix +
" ..");
649 ss << std::endl << prefix <<
" - " << v.getAllocFactory().to_string();