1 // Copyright 2014 The Android Open Source Project
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 #pragma once
16 
17 #include <string>
18 #include <type_traits>
19 #include <utility>
20 
21 #include <stdarg.h>
22 
23 namespace gfxstream {
24 namespace guest {
25 
26 // Create a new string instance that contains the printf-style formatted
27 // output from |format| and potentially any following arguments.
28 std::string StringFormatRaw(const char* format, ...);
29 
30 // A variant of StringFormat() which uses a va_list to list formatting
31 // parameters instead.
32 std::string StringFormatWithArgs(const char* format, va_list args);
33 
34 // Appends a formatted string at the end of an existing string.
35 // |string| is the target string instance, |format| the format string,
36 // followed by any formatting parameters. This is more efficient than
37 // appending the result of StringFormat(format,...) to |*string| directly.
38 void StringAppendFormatRaw(std::string* string, const char* format, ...);
39 
40 // A variant of StringAppendFormat() that takes a va_list to list
41 // formatting parameters.
42 void StringAppendFormatWithArgs(std::string* string,
43                                 const char* format,
44                                 va_list args);
45 
46 // unpackFormatArg() is a set of overloaded functions needed to unpack
47 // an argument of the formatting list to a POD value which can be passed
48 // into the sprintf()-like C function
49 
50 // Anything which can be used to construct a string goes here and unpacks into
51 // a const char*
unpackFormatArg(const std::string & str)52 inline const char* unpackFormatArg(const std::string& str) {
53     return str.c_str();
54 }
55 
56 // Forward all PODs as-is
57 template <class T>
58 constexpr T&& unpackFormatArg(T&& t,
59         typename std::enable_if<
60                     std::is_pod<typename std::decay<T>::type>::value
61                  >::type* = nullptr) {
62     return std::forward<T>(t);
63 }
64 
65 // These templated versions of StringFormat*() allow one to pass all kinds of
66 // string objects into the argument list
67 template <class... Args>
StringFormat(const char * format,Args &&...args)68 std::string StringFormat(const char* format, Args&&... args) {
69     return StringFormatRaw(format, unpackFormatArg(std::forward<Args>(args))...);
70 }
71 
72 template <class... Args>
StringAppendFormat(std::string * string,const char * format,Args &&...args)73 void StringAppendFormat(std::string* string,
74                         const char* format,
75                         Args&&... args) {
76     StringAppendFormatRaw(string, format,
77                           unpackFormatArg(std::forward<Args>(args))...);
78 }
79 
80 }  // namespace base
81 }  // namespace android
82