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