forked from objectcomputing/mFAST
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessage_printer.h
More file actions
140 lines (115 loc) · 2.7 KB
/
message_printer.h
File metadata and controls
140 lines (115 loc) · 2.7 KB
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
#pragma once
#include <mfast.h>
#include <iostream>
#include <boost/io/ios_state.hpp>
#include <bitset>
using namespace mfast;
class indenter
{
std::size_t level_;
public:
indenter()
: level_(0)
{
}
indenter& operator ++()
{
++level_;
return *this;
}
indenter& operator --()
{
--level_;
return *this;
}
std::size_t blanks() const
{
return level_*2;
}
};
std::ostream&
operator << (std::ostream& os, const indenter& indent)
{
os << std::setw(indent.blanks()) << ' ';
return os;
}
class message_printer
{
std::ostream& os_;
indenter indent_;
public:
message_printer(std::ostream& os)
: os_(os)
{
}
template <typename IntType>
void visit(const int_cref<IntType>& ref)
{
// matches int32_cref, uint32_cref, int64_cref, uint64_cref
os_ << ref.value();
}
void visit(const enum_cref& ref)
{
os_ << ref.value_name();
}
void visit(const decimal_cref& ref)
{
os_ << ref.mantissa() << "*10^" << (int)ref.exponent();
}
template <typename CharType>
void visit(const string_cref<CharType>& ref)
{
// matches ascii_string_cref and unicode_string_cref
os_ << ref.c_str();
}
void visit(const byte_vector_cref& ref)
{
boost::io::ios_flags_saver ifs( os_ );
os_ << std::hex << std::setfill('0');
for (auto elem : ref){
os_ << std::setw(2) << static_cast<unsigned>(elem);
}
os_ << std::setfill(' ');
}
template <typename IntType>
void visit(const int_vector_cref<IntType>& ref)
{
// matches int32_vector_cref, uint32_vector_cref, int64_vector_cref, uint64_vector_cref
char sep[2]= { '\x0', '\x0'};
os_ << "{";
for (auto elem : ref){
os_ << sep << elem;
sep[0] = ',';
}
os_ << "}";
}
void visit(const aggregate_cref& ref, int)
{
++indent_;
for (auto&& field : ref) {
if (field.present()) {
os_ << indent_ << field.name() << ": ";
apply_accessor(*this, field);
os_ << std::endl;
}
}
--indent_;
}
void visit(const sequence_cref& ref, int)
{
size_t index = 0;
++indent_;
for (auto element : ref) {
os_ << indent_ << "[" << index++ << "]" << ":\n";
// we cannot use apply_accessor(*this, field) here, because that would only visit the
// sub-fields of the elment instead of calling visit(const aggregate_cref& ref, int)
this->visit(element, 0);
os_ << "\n";
}
--indent_;
}
void visit(const set_cref& ref)
{
os_ << "0b" << std::bitset<16>{ref.value()};
}
};