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