1 // Copyright 2014 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11
12 #pragma once
13
14 #include "android/base/StringView.h"
15
16 #include <string>
17 #include <type_traits>
18 #include <utility>
19
20 #include <stdarg.h>
21
22 namespace android {
23 namespace base {
24
25 // Create a new string instance that contains the printf-style formatted
26 // output from |format| and potentially any following arguments.
27 std::string StringFormatRaw(const char* format, ...);
28
29 // A variant of StringFormat() which uses a va_list to list formatting
30 // parameters instead.
31 std::string StringFormatWithArgs(const char* format, va_list args);
32
33 // Appends a formatted string at the end of an existing string.
34 // |string| is the target string instance, |format| the format string,
35 // followed by any formatting parameters. This is more efficient than
36 // appending the result of StringFormat(format,...) to |*string| directly.
37 void StringAppendFormatRaw(std::string* string, const char* format, ...);
38
39 // A variant of StringAppendFormat() that takes a va_list to list
40 // formatting parameters.
41 void StringAppendFormatWithArgs(std::string* string,
42 const char* format,
43 va_list args);
44
45 // unpackFormatArg() is a set of overloaded functions needed to unpack
46 // an argument of the formatting list to a POD value which can be passed
47 // into the sprintf()-like C function
48
49 // Anything which can be used to construct a string goes here and unpacks into
50 // a const char*
unpackFormatArg(const std::string & str)51 inline const char* unpackFormatArg(const std::string& str) {
52 return str.c_str();
53 }
54
55 // Forward all PODs as-is
56 template <class T>
57 constexpr T&& unpackFormatArg(T&& t,
58 typename std::enable_if<
59 std::is_pod<typename std::decay<T>::type>::value
60 >::type* = nullptr) {
61 return std::forward<T>(t);
62 }
63
64 // These templated versions of StringFormat*() allow one to pass all kinds of
65 // string objects into the argument list
66 template <class... Args>
StringFormat(const char * format,Args &&...args)67 std::string StringFormat(const char* format, Args&&... args) {
68 return StringFormatRaw(format, unpackFormatArg(std::forward<Args>(args))...);
69 }
70
71 template <class... Args>
StringAppendFormat(std::string * string,const char * format,Args &&...args)72 void StringAppendFormat(std::string* string,
73 const char* format,
74 Args&&... args) {
75 StringAppendFormatRaw(string, format,
76 unpackFormatArg(std::forward<Args>(args))...);
77 }
78
79 } // namespace base
80 } // namespace android
81