• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ranges>
23 #include <sstream>
24 #include <string>
25 #include <vector>
26 
27 namespace android {
28 
29 namespace internal {
30 template <typename T>
31 concept Container = std::ranges::range<T>;
32 }
33 
34 template <size_t N>
bitsetToString(const std::bitset<N> & bitset)35 std::string bitsetToString(const std::bitset<N>& bitset) {
36     if (bitset.none()) {
37         return "<none>";
38     }
39     return bitset.to_string();
40 }
41 
42 template <class T>
streamableToString(const T & streamable)43 std::string streamableToString(const T& streamable) {
44     std::stringstream out;
45     out << streamable;
46     return out.str();
47 }
48 
49 template <typename T>
constToString(const T & v)50 inline std::string constToString(const T& v) {
51     return std::to_string(v);
52 }
53 
54 template <>
constToString(const bool & value)55 inline std::string constToString(const bool& value) {
56     return value ? "true" : "false";
57 }
58 
59 template <>
constToString(const std::vector<bool>::reference & value)60 inline std::string constToString(const std::vector<bool>::reference& value) {
61     return value ? "true" : "false";
62 }
63 
constToString(const std::string & s)64 inline std::string constToString(const std::string& s) {
65     return s;
66 }
67 
68 /**
69  * Convert an optional type to string.
70  */
71 template <typename T>
72 inline std::string toString(const std::optional<T>& optional,
73                             std::string (*toString)(const T&) = constToString) {
74     return optional ? toString(*optional) : "<not set>";
75 }
76 
77 /**
78  * Convert a set of integral types to string.
79  */
80 template <internal::Container T>
81 std::string dumpContainer(
82         const T& container,
83         std::string (*toString)(const std::ranges::range_value_t<T>&) = constToString) {
84     std::string out;
85     for (const auto& entry : container) {
86         out += out.empty() ? "{" : ", ";
87         out += toString(entry);
88     }
89     return out.empty() ? "{}" : (out + "}");
90 }
91 
92 /**
93  * Convert a map or multimap to string. Both keys and values of the map should be integral type.
94  */
95 template <typename T>
96 std::string dumpMap(const T& map,
97                     std::string (*keyToString)(const typename T::key_type&) = constToString,
98                     std::string (*valueToString)(const typename T::mapped_type&) = constToString) {
99     std::string out;
100     for (const auto& [k, v] : map) {
101         if (!out.empty()) {
102             out += "\n";
103         }
104         out += keyToString(k) + ":" + valueToString(v);
105     }
106     return out;
107 }
108 
109 /**
110  * Convert map keys to string. The keys of the map should be integral type.
111  */
112 template <typename K, typename V>
113 std::string dumpMapKeys(const std::map<K, V>& map,
114                         std::string (*keyToString)(const K&) = constToString) {
115     std::string out;
116     for (const auto& [k, _] : map) {
117         out += out.empty() ? "{" : ", ";
118         out += keyToString(k);
119     }
120     return out.empty() ? "{}" : (out + "}");
121 }
122 
123 /** Convert a vector to a string. */
124 template <typename T>
125 std::string dumpVector(const std::vector<T>& values,
126                        std::string (*valueToString)(const T&) = constToString) {
127     std::string out;
128     for (const auto& value : values) {
129         out += out.empty() ? "[" : ", ";
130         out += valueToString(value);
131     }
132     return out.empty() ? "[]" : (out + "]");
133 }
134 
135 const char* toString(bool value);
136 
137 /**
138  * Add "prefix" to the beginning of each line in the provided string
139  * "str".
140  * The string 'str' is typically multi-line.
141  * The most common use case for this function is to add some padding
142  * when dumping state.
143  */
144 std::string addLinePrefix(std::string str, const std::string& prefix);
145 
146 } // namespace android
147