gem5
v24.0.0.0
Loading...
Searching...
No Matches
base
stl_helpers
ostream_helpers.hh
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2023 Arteris, Inc. and its applicable licensors and
3
* affiliates.
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions are
8
* met: redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer;
10
* redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution;
13
* neither the name of the copyright holders nor the names of its
14
* contributors may be used to endorse or promote products derived from
15
* this software without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
* POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#ifndef BASE_STL_HELPERS_OSTREAM_HELPERS_HH
31
#define BASE_STL_HELPERS_OSTREAM_HELPERS_HH
32
33
#include <iostream>
34
#include <memory>
35
#include <tuple>
36
#include <utility>
37
38
#include "
base/type_traits.hh
"
39
#include "magic_enum/magic_enum.hh"
40
41
namespace
gem5::stl_helpers
42
{
43
44
/*
45
* Wrap any object in a Printer object to force using a opExtract_impl printing
46
* function. This is not required for types that do not already enable
47
* operator<< in another namespace. However, to enable the special printing
48
* function for, e.g., raw pointers, those must be wrapped in a Printer.
49
*/
50
template
<
typename
T>
51
struct
Printer
52
{
53
Printer
(
const
T&
value
):
value
{
value
} {}
54
const
T&
value
;
55
};
56
57
namespace
opExtract_impl
58
{
59
60
/*
61
* In order to provide a specialization for operator<< with stl_helpers-enabled
62
* types
63
* without loosing the hability to use it with other types, a dual-dispatch
64
* mechanism is used. The only entry point in the system is through a primary
65
* dispatch function that won't resolve for non-helped types. Then, recursive
66
* calls go through the secondary dispatch interface that sort between helped
67
* and non-helped types. Helped types will enter the system back through the
68
* primary dispatch interface while other types will look for operator<<
69
* through regular lookup, especially ADL.
70
*/
71
72
template
<
typename
T>
73
std::ostream&
74
opExtractSecDisp
(std::ostream&
os
,
const
T&
v
);
75
76
template
<
typename
E>
77
std::enable_if_t<std::is_enum_v<E>,
78
std::ostream&>
79
opExtractPrimDisp
(std::ostream&
os
,
const
E
&
e
)
80
{
81
return
os
<< magic_enum::enum_name(
e
);
82
}
83
84
template
<
typename
... T>
85
std::ostream&
86
opExtractPrimDisp
(std::ostream&
os
,
const
std::tuple<T...>&
p
)
87
{
88
std::apply([&](
auto
&&...
e
) {
89
std::size_t
n
{0};
90
os
<<
'('
;
91
((
opExtractSecDisp
(
os
,
e
) << (++
n
!=
sizeof
...(T) ?
", "
:
""
)), ...);
92
os
<<
')'
;
93
},
p
);
94
return
os
;
95
}
96
97
template
<
typename
T,
typename
U>
98
std::ostream&
99
opExtractPrimDisp
(std::ostream&
os
,
const
std::pair<T, U>
&
p
)
100
{
101
return
opExtractPrimDisp
(
os
, std::tie(
p
.first,
p
.second));
102
}
103
104
template
<
typename
T>
105
std::enable_if_t<is_iterable_v<T>, std::ostream&>
106
opExtractPrimDisp
(std::ostream&
os
,
const
T&
v
)
107
{
108
os
<<
"[ "
;
109
for
(
auto
&
e
:
v
) {
110
opExtractSecDisp
(
os
,
e
) <<
", "
;
111
}
112
return
os
<<
']'
;
113
}
114
115
template
<
typename
T>
116
std::ostream&
117
opExtractPrimDisp
(std::ostream&
os
,
const
std::optional<T>& o)
118
{
119
if
(o) {
120
return
opExtractSecDisp
(
os
, *o);
121
}
else
{
122
return
os
<<
"(-)"
;
123
}
124
}
125
126
template
<
typename
T>
127
std::ostream&
128
opExtractPrimDisp
(std::ostream&
os
, T*
p
);
129
130
template
<
typename
T>
131
std::ostream&
132
opExtractPrimDisp
(std::ostream&
os
,
const
std::shared_ptr<T>&
p
)
133
{
134
return
opExtractPrimDisp
(
os
,
p
.get());
135
}
136
137
template
<
typename
T>
138
std::ostream&
139
opExtractPrimDisp
(std::ostream&
os
,
const
std::unique_ptr<T>&
p
)
140
{
141
return
opExtractPrimDisp
(
os
,
p
.get());
142
}
143
144
template
<
typename
T>
145
std::ostream&
146
opExtractPrimDisp
(std::ostream&
os
,
const
Printer<T>
&
p
);
147
148
template
<
typename
,
typename
=
void
>
149
constexpr
bool
isOpExtractNativelySupported
=
false
;
150
151
template
<
typename
T>
152
constexpr
bool
isOpExtractNativelySupported
<T,
153
std::void_t<
decltype
(
154
std::declval<std::ostream&>() << std::declval<T>())>> =
true
;
155
156
template
<
typename
,
typename
=
void
>
157
constexpr
bool
isOpExtractHelped
=
false
;
158
159
template
<
typename
T>
160
constexpr
bool
isOpExtractHelped
<T,
161
std::void_t<
decltype
(
162
opExtractPrimDisp
(std::declval<std::ostream&>(),
163
std::declval<T>()))>>
164
=
true
;
165
166
template
<
typename
T>
167
constexpr
bool
needsDispatch
=
168
isOpExtractHelped<T>
&& !
isOpExtractNativelySupported<T>
;
169
170
template
<
typename
T>
171
std::ostream&
172
opExtractPrimDisp
(std::ostream&
os
, T*
p
)
173
{
174
if
(!
p
) {
175
return
os
<<
"nullptr"
;
176
}
177
if
constexpr
(
isOpExtractHelped<T>
||
isOpExtractNativelySupported<T>
) {
178
os
<<
'('
<<
p
<<
": "
;
179
opExtractSecDisp
(
os
, *
p
);
180
return
os
<<
')'
;
181
}
else
{
182
return
os
<<
p
;
183
}
184
}
185
186
template
<
typename
T>
187
std::ostream&
188
opExtractPrimDisp
(std::ostream&
os
,
const
Printer<T>
&
p
)
189
{
190
if
constexpr
(
isOpExtractHelped<T>
) {
191
return
opExtractPrimDisp
(
os
,
p
.value);
192
}
else
{
193
return
os
<<
p
.value;
194
}
195
}
196
197
198
template
<
typename
T>
199
std::ostream&
200
opExtractSecDisp
(std::ostream&
os
,
const
T&
v
)
201
{
202
if
constexpr
(
needsDispatch<T>
) {
203
return
opExtractPrimDisp
(
os
,
v
);
204
}
else
{
205
return
os
<<
v
;
206
}
207
}
208
209
}
// namespace opExtract_impl
210
211
// use the Printer wrapper or add "using stl_helpers::operator<<" in the scope
212
// where you want to use that operator<<.
213
template
<
typename
T>
214
std::enable_if_t<opExtract_impl::needsDispatch<T>, std::ostream&>
215
operator<<
(std::ostream&
os
,
const
T&
v
)
216
{
217
return
opExtract_impl::opExtractPrimDisp
(
os
,
v
);
218
}
219
220
}
// namespace gem5::stl_helpers
221
222
#endif
// BASE_STL_HELPERS_OSTREAM_HELPERS_HH
std::pair
STL pair class.
Definition
stl.hh:58
gem5::ArmISA::v
Bitfield< 28 > v
Definition
misc_types.hh:54
gem5::ArmISA::n
Bitfield< 31 > n
Definition
misc_types.hh:540
gem5::ArmISA::e
Bitfield< 9 > e
Definition
misc_types.hh:65
gem5::MipsISA::p
Bitfield< 0 > p
Definition
pra_constants.hh:326
gem5::X86ISA::E
Bitfield< 31, 0 > E
Definition
int.hh:56
gem5::X86ISA::os
Bitfield< 17 > os
Definition
misc.hh:838
gem5::stl_helpers::opExtract_impl::opExtractSecDisp
std::ostream & opExtractSecDisp(std::ostream &os, const T &v)
Definition
ostream_helpers.hh:200
gem5::stl_helpers::opExtract_impl::isOpExtractHelped
constexpr bool isOpExtractHelped
Definition
ostream_helpers.hh:157
gem5::stl_helpers::opExtract_impl::opExtractPrimDisp
std::enable_if_t< std::is_enum_v< E >, std::ostream & > opExtractPrimDisp(std::ostream &os, const E &e)
Definition
ostream_helpers.hh:79
gem5::stl_helpers::opExtract_impl::isOpExtractNativelySupported
constexpr bool isOpExtractNativelySupported
Definition
ostream_helpers.hh:149
gem5::stl_helpers::opExtract_impl::needsDispatch
constexpr bool needsDispatch
Definition
ostream_helpers.hh:167
gem5::stl_helpers
Definition
hash_helpers.hh:49
gem5::stl_helpers::operator<<
std::enable_if_t< opExtract_impl::needsDispatch< T >, std::ostream & > operator<<(std::ostream &os, const T &v)
Definition
ostream_helpers.hh:215
gem5::stl_helpers::Printer
Definition
ostream_helpers.hh:52
gem5::stl_helpers::Printer::value
const T & value
Definition
ostream_helpers.hh:54
gem5::stl_helpers::Printer::Printer
Printer(const T &value)
Definition
ostream_helpers.hh:53
type_traits.hh
Generated on Tue Jun 18 2024 16:24:01 for gem5 by
doxygen
1.11.0