Merge "Merge "Try harder to defeat GLSL compiler dead-code optimizations" into nougat...
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuFormatUtil.hpp
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
32 namespace tcu
33 {
34 namespace Format
35 {
36
37 // Hexadecimal value formatter.
38 template <size_t NumDigits>
39 class Hex
40 {
41 public:
42         Hex (deUint64 value_) : value(value_) {}
43
44         std::ostream& toStream (std::ostream& stream) const
45         {
46                 return stream << this->toString();
47         }
48
49         std::string toString (void) const
50         {
51                 DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);
52
53                 const char longFmt[]    = {'0', 'x', '%', '0', '0' + NumDigits/10, '0' + NumDigits%10, 'l', 'l', 'x', 0};
54                 const char shortFmt[]   = {'0', 'x', '%', '0', '0' + NumDigits, 'l', 'l', 'x', 0};
55
56                 char buf[sizeof(deUint64)*2 + 3];
57                 deSprintf(buf, sizeof(buf), NumDigits > 9 ? longFmt : shortFmt, value);
58
59                 return std::string(buf);
60         }
61
62 private:
63         deUint64 value;
64 };
65
66 template <size_t NumDigits>
67 std::ostream& operator<< (std::ostream& stream, tcu::Format::Hex<NumDigits> hex)
68 {
69         return hex.toStream(stream);
70 }
71
72 // Bitfield formatter.
73
74 class BitDesc
75 {
76 public:
77         deUint64        bit;
78         const char*     name;
79
80         BitDesc (deUint64 bit_, const char* name_) : bit(bit_), name(name_) {}
81 };
82
83 #define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT)
84
85 template <size_t BitfieldSize>
86 class Bitfield
87 {
88 public:
89         Bitfield (deUint64 value, const BitDesc* begin, const BitDesc* end)
90                 : m_value       (value)
91                 , m_begin       (begin)
92                 , m_end         (end)
93         {
94         }
95
96         std::ostream& toStream (std::ostream& stream)
97         {
98                 deUint64 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         deUint64                        m_value;
122         const BitDesc*          m_begin;
123         const BitDesc*          m_end;
124 };
125
126 template <size_t BitfieldSize>
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
140         Enum (GetNameFunc getName, T value)
141                 : m_getName     (getName)
142                 , m_value (value)
143         {
144         }
145
146         std::ostream& toStream (std::ostream& stream) const
147         {
148                 const char* name = m_getName(m_value);
149                 if (name)
150                         return stream << name;
151                 else
152                         return stream << Hex<NumBytes*2>((deUint64)m_value);
153         }
154
155         std::string toString (void) const
156         {
157                 const char* name = m_getName(m_value);
158                 if (name)
159                         return std::string(name);
160                 else
161                         return Hex<NumBytes*2>((deUint64)m_value).toString();
162         }
163
164 private:
165         const GetNameFunc       m_getName;
166         const T                         m_value;
167 };
168
169 template <typename T, size_t NumBytes>
170 inline std::ostream& operator<< (std::ostream& stream, const Enum<T, NumBytes>& fmt) { return fmt.toStream(stream); }
171
172 // Array formatters.
173
174 template <typename Iterator>
175 class Array
176 {
177 public:
178         Iterator        begin;
179         Iterator        end;
180
181         Array (const Iterator& begin_, const Iterator& end_) : begin(begin_), end(end_) {}
182 };
183
184 template <typename T>
185 class ArrayPointer
186 {
187 public:
188         const T*        arr;
189         int                     size;
190
191         ArrayPointer (const T* arr_, int size_) : arr(arr_), size(size_) {}
192 };
193
194 template <typename Iterator>
195 std::ostream& operator<< (std::ostream& str, const Array<Iterator>& fmt)
196 {
197         str << "{ ";
198         for (Iterator cur = fmt.begin; cur != fmt.end; ++cur)
199         {
200                 if (cur != fmt.begin)
201                         str << ", ";
202                 str << *cur;
203         }
204         str << " }";
205         return str;
206 }
207
208 template <typename T>
209 std::ostream& operator<< (std::ostream& str, const ArrayPointer<T>& fmt)
210 {
211         if (fmt.arr != DE_NULL)
212                 return str << Array<const T*>(fmt.arr, fmt.arr+fmt.size);
213         else
214                 return str << "(null)";
215 }
216
217 // Hex format iterator (useful for combining with ArrayFormatter).
218 // \todo [2012-10-30 pyry] Implement more generic format iterator.
219
220 template <typename T, typename Iterator = const T*>
221 class HexIterator
222 {
223 public:
224                                                                                 HexIterator                     (Iterator iter) : m_iter(iter) {}
225
226         HexIterator<T, Iterator>&                       operator++                      (void)  { ++m_iter; return *this;               }
227         HexIterator<T, Iterator>                        operator++                      (int)   { return HexIterator(m_iter++); }
228
229         bool                                                            operator==                      (const HexIterator<T, Iterator>& other) const { return m_iter == other.m_iter; }
230         bool                                                            operator!=                      (const HexIterator<T, Iterator>& other) const { return m_iter != other.m_iter; }
231
232 #if !defined(__INTELLISENSE__)
233         // Intellisense in VS2013 crashes when parsing this.
234         Hex<sizeof(T)*2>                                        operator*                       (void) const { return Hex<sizeof(T)*2>(*m_iter);        }
235 #endif
236
237 private:
238         Iterator                                                        m_iter;
239 };
240
241 } // Format
242
243 template <int Bits>             inline deUint64 makeMask64                      (void)                          { return (1ull<<Bits)-1;                                                                }
244 template <>                             inline deUint64 makeMask64<64>          (void)                          { return ~0ull;                                                                                 }
245 template <typename T>   inline deUint64 toUint64                        (T value)                       { return (deUint64)value & makeMask64<sizeof(T)*8>();   }
246
247 /** Format value as hexadecimal number. */
248 template <size_t NumDigits, typename T>
249 inline Format::Hex<NumDigits> toHex (T value)
250 {
251         return Format::Hex<NumDigits>(toUint64(value));
252 }
253
254 /** Format value as hexadecimal number. */
255 template <typename T>
256 inline Format::Hex<sizeof(T)*2> toHex (T value)
257 {
258         return Format::Hex<sizeof(T)*2>(toUint64(value));
259 }
260
261 /** Decode and format bitfield. */
262 template <typename T, size_t Size>
263 inline Format::Bitfield<sizeof(T)*8> formatBitfield (T value, const Format::BitDesc (&desc)[Size])
264 {
265         return Format::Bitfield<sizeof(T)*8>((deUint64)value, &desc[0], &desc[Size]);
266 }
267
268 /** Format array contents. */
269 template <typename Iterator>
270 inline Format::Array<Iterator> formatArray (const Iterator& begin, const Iterator& end)
271 {
272         return Format::Array<Iterator>(begin, end);
273 }
274
275 /** Format array contents. */
276 template <typename T>
277 inline Format::ArrayPointer<T> formatArray (const T* arr, int size)
278 {
279         return Format::ArrayPointer<T>(arr, size);
280 }
281
282 /** Format array contents. */
283 template <typename T, int Size>
284 inline Format::ArrayPointer<T> formatArray (const T (&arr)[Size])
285 {
286         return Format::ArrayPointer<T>(arr, Size);
287 }
288
289 } // tcu
290
291 #endif // _TCUFORMATUTIL_HPP