indented std::ostream w/ xalloc()

This commit is contained in:
Michael Davidsaver
2020-07-24 18:18:58 -07:00
parent e8649ecdd2
commit 9328d193af
5 changed files with 151 additions and 41 deletions
+81 -7
View File
@@ -121,6 +121,87 @@ CASE(SubscriptionImpl);
return ret;
}
// _assume_ only positive indices will be used
static
std::atomic<int> indentIndex{INT_MIN};
std::ostream& operator<<(std::ostream& strm, const indent&)
{
auto idx = indentIndex.load(std::memory_order_relaxed);
if(idx!=INT_MIN) {
auto n = strm.iword(idx);
for(auto i : range(n)) {
(void)i;
strm<<" ";
}
}
return strm;
}
Indented::Indented(std::ostream& strm, int depth)
:strm(&strm)
,depth(depth)
{
auto idx = indentIndex.load();
if(idx==INT_MIN) {
auto newidx = std::ostream::xalloc();
if(indentIndex.compare_exchange_strong(idx, newidx)) {
idx = newidx;
} else {
// lost race. no way to undo xalloc(), so just wasted...
idx = indentIndex.load();
}
}
strm.iword(idx) += depth;
}
Indented::~Indented()
{
if(strm)
strm->iword(indentIndex.load()) -= depth;
}
// _assume_ only positive indices will be used
static
std::atomic<int> detailIndex{INT_MIN};
Detailed::Detailed(std::ostream& strm, int lvl)
:strm(&strm)
{
auto idx = detailIndex.load();
if(idx==INT_MIN) {
auto newidx = std::ostream::xalloc();
if(detailIndex.compare_exchange_strong(idx, newidx)) {
idx = newidx;
} else {
// lost race. no way to undo xalloc(), so just wasted...
idx = detailIndex.load();
}
}
auto& ref = strm.iword(idx);
this->lvl = ref;
ref = lvl;
}
Detailed::~Detailed()
{
if(strm)
strm->iword(detailIndex.load()) = lvl;
}
int Detailed::level(std::ostream &strm)
{
int ret = 0;
auto idx = detailIndex.load(std::memory_order_relaxed);
if(idx==INT_MIN) {
strm<<"Hint: Wrap with pvxs::Detailed()\n";
} else {
ret = strm.iword(idx);
}
return ret;
}
namespace detail {
Escaper::Escaper(const char* v)
@@ -434,11 +515,4 @@ int64_t parseTo<int64_t>(const std::string& s) {
return ret;
}
void indent(std::ostream& strm, unsigned level) {
for(auto i : range(level)) {
(void)i;
strm<<" ";
}
}
}}