1// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#ifndef _INFOSINK_INCLUDED_ 16#define _INFOSINK_INCLUDED_ 17 18#include <math.h> 19#include "Common.h" 20 21// Returns the fractional part of the given floating-point number. 22inline float fractionalPart(float f) { 23 float intPart = 0.0f; 24 return modff(f, &intPart); 25} 26 27// 28// TPrefixType is used to centralize how info log messages start. 29// See below. 30// 31enum TPrefixType { 32 EPrefixNone, 33 EPrefixWarning, 34 EPrefixError, 35 EPrefixInternalError, 36 EPrefixUnimplemented, 37 EPrefixNote 38}; 39 40// 41// Encapsulate info logs for all objects that have them. 42// 43// The methods are a general set of tools for getting a variety of 44// messages and types inserted into the log. 45// 46class TInfoSinkBase { 47public: 48 TInfoSinkBase() {} 49 50 template <typename T> 51 TInfoSinkBase& operator<<(const T& t) { 52 TPersistStringStream stream; 53 stream << t; 54 sink.append(stream.str()); 55 return *this; 56 } 57 // Override << operator for specific types. It is faster to append strings 58 // and characters directly to the sink. 59 TInfoSinkBase& operator<<(char c) { 60 sink.append(1, c); 61 return *this; 62 } 63 TInfoSinkBase& operator<<(const char* str) { 64 sink.append(str); 65 return *this; 66 } 67 TInfoSinkBase& operator<<(const TPersistString& str) { 68 sink.append(str); 69 return *this; 70 } 71 TInfoSinkBase& operator<<(const TString& str) { 72 sink.append(str.c_str()); 73 return *this; 74 } 75 // Make sure floats are written with correct precision. 76 TInfoSinkBase& operator<<(float f) { 77 // Make sure that at least one decimal point is written. If a number 78 // does not have a fractional part, the default precision format does 79 // not write the decimal portion which gets interpreted as integer by 80 // the compiler. 81 TPersistStringStream stream; 82 if (fractionalPart(f) == 0.0f) { 83 stream.precision(1); 84 stream << std::showpoint << std::fixed << f; 85 } else { 86 stream.unsetf(std::ios::fixed); 87 stream.unsetf(std::ios::scientific); 88 stream.precision(8); 89 stream << f; 90 } 91 sink.append(stream.str()); 92 return *this; 93 } 94 // Write boolean values as their names instead of integral value. 95 TInfoSinkBase& operator<<(bool b) { 96 const char* str = b ? "true" : "false"; 97 sink.append(str); 98 return *this; 99 } 100 101 void erase() { sink.clear(); } 102 int size() { return static_cast<int>(sink.size()); } 103 104 const TPersistString& str() const { return sink; } 105 const char* c_str() const { return sink.c_str(); } 106 107 void prefix(TPrefixType message); 108 void location(const TSourceLoc& loc); 109 void message(TPrefixType message, const char* s); 110 void message(TPrefixType message, const char* s, TSourceLoc loc); 111 112private: 113 TPersistString sink; 114}; 115 116class TInfoSink { 117public: 118 TInfoSinkBase info; 119 TInfoSinkBase debug; 120 TInfoSinkBase obj; 121}; 122 123#endif // _INFOSINK_INCLUDED_ 124