1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #pragma once
18
19 #include <bitset>
20 #include <map>
21 #include <optional>
22 #include <set>
23 #include <sstream>
24 #include <string>
25 #include <vector>
26
27 namespace android {
28
29 template <size_t N>
bitsetToString(const std::bitset<N> & bitset)30 std::string bitsetToString(const std::bitset<N>& bitset) {
31 if (bitset.none()) {
32 return "<none>";
33 }
34 return bitset.to_string();
35 }
36
37 template <class T>
streamableToString(const T & streamable)38 std::string streamableToString(const T& streamable) {
39 std::stringstream out;
40 out << streamable;
41 return out.str();
42 }
43
44 template <typename T>
constToString(const T & v)45 inline std::string constToString(const T& v) {
46 return std::to_string(v);
47 }
48
49 template <>
constToString(const bool & value)50 inline std::string constToString(const bool& value) {
51 return value ? "true" : "false";
52 }
53
54 template <>
constToString(const std::vector<bool>::reference & value)55 inline std::string constToString(const std::vector<bool>::reference& value) {
56 return value ? "true" : "false";
57 }
58
constToString(const std::string & s)59 inline std::string constToString(const std::string& s) {
60 return s;
61 }
62
63 /**
64 * Convert an optional type to string.
65 */
66 template <typename T>
67 inline std::string toString(const std::optional<T>& optional,
68 std::string (*toString)(const T&) = constToString) {
69 return optional ? toString(*optional) : "<not set>";
70 }
71
72 /**
73 * Convert a set of integral types to string.
74 */
75 template <typename T>
76 std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) {
77 std::string out;
78 for (const T& entry : v) {
79 out += out.empty() ? "{" : ", ";
80 out += toString(entry);
81 }
82 return out.empty() ? "{}" : (out + "}");
83 }
84
85 /**
86 * Convert a map or multimap to string. Both keys and values of the map should be integral type.
87 */
88 template <typename T>
89 std::string dumpMap(const T& map,
90 std::string (*keyToString)(const typename T::key_type&) = constToString,
91 std::string (*valueToString)(const typename T::mapped_type&) = constToString) {
92 std::string out;
93 for (const auto& [k, v] : map) {
94 if (!out.empty()) {
95 out += "\n";
96 }
97 out += keyToString(k) + ":" + valueToString(v);
98 }
99 return out;
100 }
101
102 /**
103 * Convert map keys to string. The keys of the map should be integral type.
104 */
105 template <typename K, typename V>
106 std::string dumpMapKeys(const std::map<K, V>& map,
107 std::string (*keyToString)(const K&) = constToString) {
108 std::string out;
109 for (const auto& [k, _] : map) {
110 out += out.empty() ? "{" : ", ";
111 out += keyToString(k);
112 }
113 return out.empty() ? "{}" : (out + "}");
114 }
115
116 /** Convert a vector to a string. */
117 template <typename T>
118 std::string dumpVector(const std::vector<T>& values,
119 std::string (*valueToString)(const T&) = constToString) {
120 std::string out;
121 for (const auto& value : values) {
122 out += out.empty() ? "[" : ", ";
123 out += valueToString(value);
124 }
125 return out.empty() ? "[]" : (out + "]");
126 }
127
128 const char* toString(bool value);
129
130 /**
131 * Add "prefix" to the beginning of each line in the provided string
132 * "str".
133 * The string 'str' is typically multi-line.
134 * The most common use case for this function is to add some padding
135 * when dumping state.
136 */
137 std::string addLinePrefix(std::string str, const std::string& prefix);
138
139 } // namespace android
140