1 #ifndef _TCUFORMATUTIL_HPP
2 #define _TCUFORMATUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
7 * Copyright 2014 The Android Open Source Project
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief String format utilities.
24 *//*--------------------------------------------------------------------*/
26 #include "tcuDefs.hpp"
37 // Hexadecimal value formatter.
38 template <size_t NumDigits>
42 Hex (deUint64 value_) : value(value_) {}
44 std::ostream& toStream (std::ostream& stream) const
46 return stream << this->toString();
49 std::string toString (void) const
51 DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16);
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};
56 char buf[sizeof(deUint64)*2 + 3];
57 deSprintf(buf, sizeof(buf), NumDigits > 9 ? longFmt : shortFmt, value);
59 return std::string(buf);
66 template <size_t NumDigits>
67 std::ostream& operator<< (std::ostream& stream, tcu::Format::Hex<NumDigits> hex)
69 return hex.toStream(stream);
72 // Bitfield formatter.
80 BitDesc (deUint64 bit_, const char* name_) : bit(bit_), name(name_) {}
83 #define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT)
85 template <size_t BitfieldSize>
89 Bitfield (deUint64 value, const BitDesc* begin, const BitDesc* end)
96 std::ostream& toStream (std::ostream& stream)
98 deUint64 bitsLeft = m_value;
99 for (const BitDesc* curDesc = m_begin; curDesc != m_end; curDesc++)
101 if (curDesc->bit & bitsLeft)
103 if (bitsLeft != m_value)
105 stream << curDesc->name;
106 bitsLeft ^= curDesc->bit;
112 if (bitsLeft != m_value)
114 stream << Hex<BitfieldSize/4>(bitsLeft);
122 const BitDesc* m_begin;
123 const BitDesc* m_end;
126 template <size_t BitfieldSize>
127 inline std::ostream& operator<< (std::ostream& stream, Bitfield<BitfieldSize> decoder)
129 return decoder.toStream(stream);
133 // \todo [2012-10-30 pyry] Use template for GetName.
134 template <typename T, size_t NumBytes = sizeof(T)>
138 typedef const char* (*GetNameFunc) (T value);
140 Enum (GetNameFunc getName, T value)
141 : m_getName (getName)
146 std::ostream& toStream (std::ostream& stream) const
148 const char* name = m_getName(m_value);
150 return stream << name;
152 return stream << Hex<NumBytes*2>((deUint64)m_value);
155 std::string toString (void) const
157 const char* name = m_getName(m_value);
159 return std::string(name);
161 return Hex<NumBytes*2>((deUint64)m_value).toString();
165 const GetNameFunc m_getName;
169 template <typename T, size_t NumBytes>
170 inline std::ostream& operator<< (std::ostream& stream, const Enum<T, NumBytes>& fmt) { return fmt.toStream(stream); }
174 template <typename Iterator>
181 Array (const Iterator& begin_, const Iterator& end_) : begin(begin_), end(end_) {}
184 template <typename T>
191 ArrayPointer (const T* arr_, int size_) : arr(arr_), size(size_) {}
194 template <typename Iterator>
195 std::ostream& operator<< (std::ostream& str, const Array<Iterator>& fmt)
198 for (Iterator cur = fmt.begin; cur != fmt.end; ++cur)
200 if (cur != fmt.begin)
208 template <typename T>
209 std::ostream& operator<< (std::ostream& str, const ArrayPointer<T>& fmt)
211 if (fmt.arr != DE_NULL)
212 return str << Array<const T*>(fmt.arr, fmt.arr+fmt.size);
214 return str << "(null)";
217 // Hex format iterator (useful for combining with ArrayFormatter).
218 // \todo [2012-10-30 pyry] Implement more generic format iterator.
220 template <typename T, typename Iterator = const T*>
224 HexIterator (Iterator iter) : m_iter(iter) {}
226 HexIterator<T, Iterator>& operator++ (void) { ++m_iter; return *this; }
227 HexIterator<T, Iterator> operator++ (int) { return HexIterator(m_iter++); }
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; }
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); }
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>(); }
247 /** Format value as hexadecimal number. */
248 template <size_t NumDigits, typename T>
249 inline Format::Hex<NumDigits> toHex (T value)
251 return Format::Hex<NumDigits>(toUint64(value));
254 /** Format value as hexadecimal number. */
255 template <typename T>
256 inline Format::Hex<sizeof(T)*2> toHex (T value)
258 return Format::Hex<sizeof(T)*2>(toUint64(value));
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])
265 return Format::Bitfield<sizeof(T)*8>((deUint64)value, &desc[0], &desc[Size]);
268 /** Format array contents. */
269 template <typename Iterator>
270 inline Format::Array<Iterator> formatArray (const Iterator& begin, const Iterator& end)
272 return Format::Array<Iterator>(begin, end);
275 /** Format array contents. */
276 template <typename T>
277 inline Format::ArrayPointer<T> formatArray (const T* arr, int size)
279 return Format::ArrayPointer<T>(arr, size);
282 /** Format array contents. */
283 template <typename T, int Size>
284 inline Format::ArrayPointer<T> formatArray (const T (&arr)[Size])
286 return Format::ArrayPointer<T>(arr, Size);
291 #endif // _TCUFORMATUTIL_HPP