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. |
22 | inline 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 | // |
31 | enum TPrefixType { |
32 | EPrefixNone, |
33 | EPrefixInfo, |
34 | EPrefixWarning, |
35 | EPrefixError, |
36 | EPrefixInternalError, |
37 | EPrefixUnimplemented, |
38 | EPrefixNote |
39 | }; |
40 | |
41 | // |
42 | // Encapsulate info logs for all objects that have them. |
43 | // |
44 | // The methods are a general set of tools for getting a variety of |
45 | // messages and types inserted into the log. |
46 | // |
47 | class TInfoSinkBase { |
48 | public: |
49 | TInfoSinkBase() {} |
50 | |
51 | template <typename T> |
52 | TInfoSinkBase& operator<<(const T& t) { |
53 | TPersistStringStream stream; |
54 | stream << t; |
55 | sink.append(stream.str()); |
56 | return *this; |
57 | } |
58 | // Override << operator for specific types. It is faster to append strings |
59 | // and characters directly to the sink. |
60 | TInfoSinkBase& operator<<(char c) { |
61 | sink.append(1, c); |
62 | return *this; |
63 | } |
64 | TInfoSinkBase& operator<<(const char* str) { |
65 | sink.append(str); |
66 | return *this; |
67 | } |
68 | TInfoSinkBase& operator<<(const TPersistString& str) { |
69 | sink.append(str); |
70 | return *this; |
71 | } |
72 | TInfoSinkBase& operator<<(const TString& str) { |
73 | sink.append(str.c_str()); |
74 | return *this; |
75 | } |
76 | // Make sure floats are written with correct precision. |
77 | TInfoSinkBase& operator<<(float f) { |
78 | // Make sure that at least one decimal point is written. If a number |
79 | // does not have a fractional part, the default precision format does |
80 | // not write the decimal portion which gets interpreted as integer by |
81 | // the compiler. |
82 | TPersistStringStream stream; |
83 | if (fractionalPart(f) == 0.0f) { |
84 | stream.precision(1); |
85 | stream << std::showpoint << std::fixed << f; |
86 | } else { |
87 | stream.unsetf(std::ios::fixed); |
88 | stream.unsetf(std::ios::scientific); |
89 | stream.precision(8); |
90 | stream << f; |
91 | } |
92 | sink.append(stream.str()); |
93 | return *this; |
94 | } |
95 | // Write boolean values as their names instead of integral value. |
96 | TInfoSinkBase& operator<<(bool b) { |
97 | const char* str = b ? "true" : "false" ; |
98 | sink.append(str); |
99 | return *this; |
100 | } |
101 | |
102 | void erase() { sink.clear(); } |
103 | int size() { return static_cast<int>(sink.size()); } |
104 | |
105 | const TPersistString& str() const { return sink; } |
106 | const char* c_str() const { return sink.c_str(); } |
107 | |
108 | void prefix(TPrefixType message); |
109 | void location(const TSourceLoc& loc); |
110 | void message(TPrefixType message, const char* s); |
111 | void message(TPrefixType message, const char* s, TSourceLoc loc); |
112 | |
113 | private: |
114 | TPersistString sink; |
115 | }; |
116 | |
117 | class TInfoSink { |
118 | public: |
119 | TInfoSinkBase info; |
120 | TInfoSinkBase debug; |
121 | TInfoSinkBase obj; |
122 | }; |
123 | |
124 | #endif // _INFOSINK_INCLUDED_ |
125 | |