1 // 2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 #ifndef _INFOSINK_INCLUDED_ 8 #define _INFOSINK_INCLUDED_ 9 10 #include <math.h> 11 #include <stdlib.h> 12 #include "compiler/Common.h" 13 14 // Returns the fractional part of the given floating-point number. 15 inline float fractionalPart(float f) { 16 float intPart = 0.0f; 17 return modff(f, &intPart); 18 } 19 20 // 21 // TPrefixType is used to centralize how info log messages start. 22 // See below. 23 // 24 enum TPrefixType { 25 EPrefixNone, 26 EPrefixWarning, 27 EPrefixError, 28 EPrefixInternalError, 29 EPrefixUnimplemented, 30 EPrefixNote 31 }; 32 33 // 34 // Encapsulate info logs for all objects that have them. 35 // 36 // The methods are a general set of tools for getting a variety of 37 // messages and types inserted into the log. 38 // 39 class TInfoSinkBase { 40 public: 41 TInfoSinkBase() {} 42 43 template <typename T> 44 TInfoSinkBase& operator<<(const T& t) { 45 TPersistStringStream stream; 46 stream << t; 47 sink.append(stream.str()); 48 return *this; 49 } 50 // Override << operator for specific types. It is faster to append strings 51 // and characters directly to the sink. 52 TInfoSinkBase& operator<<(char c) { 53 sink.append(1, c); 54 return *this; 55 } 56 TInfoSinkBase& operator<<(const char* str) { 57 sink.append(str); 58 return *this; 59 } 60 TInfoSinkBase& operator<<(const TPersistString& str) { 61 sink.append(str); 62 return *this; 63 } 64 TInfoSinkBase& operator<<(const TString& str) { 65 sink.append(str.c_str()); 66 return *this; 67 } 68 // Make sure floats are written with correct precision. 69 TInfoSinkBase& operator<<(float f) { 70 // Make sure that at least one decimal point is written. If a number 71 // does not have a fractional part, the default precision format does 72 // not write the decimal portion which gets interpreted as integer by 73 // the compiler. 74 TPersistStringStream stream; 75 if (fractionalPart(f) == 0.0f) { 76 stream.precision(1); 77 stream << std::showpoint << std::fixed << f; 78 } else { 79 stream.unsetf(std::ios::fixed); 80 stream.unsetf(std::ios::scientific); 81 stream.precision(8); 82 stream << f; 83 } 84 sink.append(stream.str()); 85 return *this; 86 } 87 // Write boolean values as their names instead of integral value. 88 TInfoSinkBase& operator<<(bool b) { 89 const char* str = b ? "true" : "false"; 90 sink.append(str); 91 return *this; 92 } 93 94 void erase() { sink.clear(); } 95 int size() { return static_cast<int>(sink.size()); } 96 97 const TPersistString& str() const { return sink; } 98 const char* c_str() const { return sink.c_str(); } 99 100 void prefix(TPrefixType p); 101 void location(int file, int line); 102 void location(const TSourceLoc& loc); 103 void message(TPrefixType p, const TSourceLoc& loc, const char* m); 104 105 private: 106 TPersistString sink; 107 }; 108 109 class TInfoSink { 110 public: 111 TInfoSinkBase info; 112 TInfoSinkBase debug; 113 TInfoSinkBase obj; 114 }; 115 116 #endif // _INFOSINK_INCLUDED_ 117