xref: /aosp_15_r20/external/deqp/framework/common/tcuFormatUtil.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _TCUFORMATUTIL_HPP
2 #define _TCUFORMATUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief String format utilities.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "deString.h"
28 
29 #include <ostream>
30 #include <string>
31 #include <sstream>
32 #include <iomanip>
33 
34 namespace tcu
35 {
36 namespace Format
37 {
38 
39 // Hexadecimal value formatter.
40 template <size_t NumDigits>
41 class Hex
42 {
43 public:
Hex(uint64_t value_)44     Hex(uint64_t value_) : value(value_)
45     {
46     }
47 
toStream(std::ostream & stream) const48     std::ostream &toStream(std::ostream &stream) const
49     {
50         DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);
51 
52         return stream << "0x" << std::right << std::setfill('0') << std::setw(NumDigits) << std::hex << value;
53     }
54 
toString(void) const55     std::string toString(void) const
56     {
57         std::stringstream stream;
58 
59         toStream(stream);
60         return stream.str();
61     }
62 
63 private:
64     uint64_t value;
65 };
66 
67 template <size_t NumDigits>
operator <<(std::ostream & stream,tcu::Format::Hex<NumDigits> hex)68 std::ostream &operator<<(std::ostream &stream, tcu::Format::Hex<NumDigits> hex)
69 {
70     return hex.toStream(stream);
71 }
72 
73 // Bitfield formatter.
74 
75 class BitDesc
76 {
77 public:
78     uint64_t bit;
79     const char *name;
80 
BitDesc(uint64_t bit_,const char * name_)81     BitDesc(uint64_t bit_, const char *name_) : bit(bit_), name(name_)
82     {
83     }
84 };
85 
86 #define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT)
87 
88 template <size_t BitfieldSize>
89 class Bitfield
90 {
91 public:
Bitfield(uint64_t value,const BitDesc * begin,const BitDesc * end)92     Bitfield(uint64_t value, const BitDesc *begin, const BitDesc *end) : m_value(value), m_begin(begin), m_end(end)
93     {
94     }
95 
toStream(std::ostream & stream)96     std::ostream &toStream(std::ostream &stream)
97     {
98         uint64_t bitsLeft = m_value;
99         for (const BitDesc *curDesc = m_begin; curDesc != m_end; curDesc++)
100         {
101             if (curDesc->bit & bitsLeft)
102             {
103                 if (bitsLeft != m_value)
104                     stream << "|";
105                 stream << curDesc->name;
106                 bitsLeft ^= curDesc->bit;
107             }
108         }
109 
110         if (bitsLeft != 0)
111         {
112             if (bitsLeft != m_value)
113                 stream << "|";
114             stream << Hex<BitfieldSize / 4>(bitsLeft);
115         }
116 
117         return stream;
118     }
119 
120 private:
121     uint64_t m_value;
122     const BitDesc *m_begin;
123     const BitDesc *m_end;
124 };
125 
126 template <size_t BitfieldSize>
operator <<(std::ostream & stream,Bitfield<BitfieldSize> decoder)127 inline std::ostream &operator<<(std::ostream &stream, Bitfield<BitfieldSize> decoder)
128 {
129     return decoder.toStream(stream);
130 }
131 
132 // Enum formatter.
133 // \todo [2012-10-30 pyry] Use template for GetName.
134 template <typename T, size_t NumBytes = sizeof(T)>
135 class Enum
136 {
137 public:
138     typedef const char *(*GetNameFunc)(T value);
139 
Enum(GetNameFunc getName,T value)140     Enum(GetNameFunc getName, T value) : m_getName(getName), m_value(value)
141     {
142     }
143 
toStream(std::ostream & stream) const144     std::ostream &toStream(std::ostream &stream) const
145     {
146         const char *name = m_getName(m_value);
147         if (name)
148             return stream << name;
149         else
150             return stream << Hex<NumBytes * 2>((uint64_t)m_value);
151     }
152 
toString(void) const153     std::string toString(void) const
154     {
155         const char *name = m_getName(m_value);
156         if (name)
157             return std::string(name);
158         else
159             return Hex<NumBytes * 2>((uint64_t)m_value).toString();
160     }
161 
162 private:
163     const GetNameFunc m_getName;
164     const T m_value;
165 };
166 
167 template <typename T, size_t NumBytes>
operator <<(std::ostream & stream,const Enum<T,NumBytes> & fmt)168 inline std::ostream &operator<<(std::ostream &stream, const Enum<T, NumBytes> &fmt)
169 {
170     return fmt.toStream(stream);
171 }
172 
173 // Array formatters.
174 
175 template <typename Iterator>
176 class Array
177 {
178 public:
179     Iterator begin;
180     Iterator end;
181 
Array(const Iterator & begin_,const Iterator & end_)182     Array(const Iterator &begin_, const Iterator &end_) : begin(begin_), end(end_)
183     {
184     }
185 };
186 
187 template <typename T>
188 class ArrayPointer
189 {
190 public:
191     const T *arr;
192     int size;
193 
ArrayPointer(const T * arr_,int size_)194     ArrayPointer(const T *arr_, int size_) : arr(arr_), size(size_)
195     {
196     }
197 };
198 
199 template <typename Iterator>
operator <<(std::ostream & str,const Array<Iterator> & fmt)200 std::ostream &operator<<(std::ostream &str, const Array<Iterator> &fmt)
201 {
202     str << "{ ";
203     for (Iterator cur = fmt.begin; cur != fmt.end; ++cur)
204     {
205         if (cur != fmt.begin)
206             str << ", ";
207         str << *cur;
208     }
209     str << " }";
210     return str;
211 }
212 
213 template <typename T>
operator <<(std::ostream & str,const ArrayPointer<T> & fmt)214 std::ostream &operator<<(std::ostream &str, const ArrayPointer<T> &fmt)
215 {
216     if (fmt.arr != DE_NULL)
217         return str << Array<const T *>(fmt.arr, fmt.arr + fmt.size);
218     else
219         return str << "(null)";
220 }
221 
222 // Hex format iterator (useful for combining with ArrayFormatter).
223 // \todo [2012-10-30 pyry] Implement more generic format iterator.
224 
225 template <typename T, typename Iterator = const T *>
226 class HexIterator
227 {
228 public:
HexIterator(Iterator iter)229     HexIterator(Iterator iter) : m_iter(iter)
230     {
231     }
232 
operator ++(void)233     HexIterator<T, Iterator> &operator++(void)
234     {
235         ++m_iter;
236         return *this;
237     }
operator ++(int)238     HexIterator<T, Iterator> operator++(int)
239     {
240         return HexIterator(m_iter++);
241     }
242 
operator ==(const HexIterator<T,Iterator> & other) const243     bool operator==(const HexIterator<T, Iterator> &other) const
244     {
245         return m_iter == other.m_iter;
246     }
operator !=(const HexIterator<T,Iterator> & other) const247     bool operator!=(const HexIterator<T, Iterator> &other) const
248     {
249         return m_iter != other.m_iter;
250     }
251 
252 #if !defined(__INTELLISENSE__)
253     // Intellisense in VS2013 crashes when parsing this.
operator *(void) const254     Hex<sizeof(T) * 2> operator*(void) const
255     {
256         return Hex<sizeof(T) * 2>(*m_iter);
257     }
258 #endif
259 
260 private:
261     Iterator m_iter;
262 };
263 
264 } // namespace Format
265 
266 template <int Bits>
makeMask64(void)267 inline uint64_t makeMask64(void)
268 {
269     return (1ull << Bits) - 1;
270 }
271 template <>
makeMask64(void)272 inline uint64_t makeMask64<64>(void)
273 {
274     return ~0ull;
275 }
276 template <typename T>
toUint64(T value)277 inline uint64_t toUint64(T value)
278 {
279     return (uint64_t)value & makeMask64<sizeof(T) * 8>();
280 }
281 
282 /** Format value as hexadecimal number. */
283 template <size_t NumDigits, typename T>
toHex(T value)284 inline Format::Hex<NumDigits> toHex(T value)
285 {
286     return Format::Hex<NumDigits>(toUint64(value));
287 }
288 
289 /** Format value as hexadecimal number. */
290 template <typename T>
toHex(T value)291 inline Format::Hex<sizeof(T) * 2> toHex(T value)
292 {
293     return Format::Hex<sizeof(T) * 2>(toUint64(value));
294 }
295 
296 /** Decode and format bitfield. */
297 template <typename T, size_t Size>
formatBitfield(T value,const Format::BitDesc (& desc)[Size])298 inline Format::Bitfield<sizeof(T) * 8> formatBitfield(T value, const Format::BitDesc (&desc)[Size])
299 {
300     return Format::Bitfield<sizeof(T) * 8>((uint64_t)value, &desc[0], &desc[Size]);
301 }
302 
303 /** Format array contents. */
304 template <typename Iterator>
formatArray(const Iterator & begin,const Iterator & end)305 inline Format::Array<Iterator> formatArray(const Iterator &begin, const Iterator &end)
306 {
307     return Format::Array<Iterator>(begin, end);
308 }
309 
310 /** Format array contents. */
311 template <typename T>
formatArray(const T * arr,int size)312 inline Format::ArrayPointer<T> formatArray(const T *arr, int size)
313 {
314     return Format::ArrayPointer<T>(arr, size);
315 }
316 
317 /** Format array contents. */
318 template <typename T, int Size>
formatArray(const T (& arr)[Size])319 inline Format::ArrayPointer<T> formatArray(const T (&arr)[Size])
320 {
321     return Format::ArrayPointer<T>(arr, Size);
322 }
323 
324 } // namespace tcu
325 
326 #endif // _TCUFORMATUTIL_HPP
327