Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_string / size_report / string_builder_size_report_incremental.cc
1 // Copyright 2019 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // This size report uses pw::StringBuilder and std::snprintf to write several
16 // strings to a buffer. Ten strings are written using pw::StringBuilder and
17 // std::snprintf, tracking the number of bytes written and whether an error
18 // occurred.
19 //
20 // This compares the incremental cost of using StringBuilder instead of
21 // std::snprintf when both are already in use in a binary.
22
23 #include <cstdio>
24
25 #include "pw_bloat/bloat_this_binary.h"
26 #include "pw_string/string_builder.h"
27
28 #if !defined(USE_STRING_BUILDER)
29 #error "USE_STRING_BUILDER must be defined"
30 #endif  // !defined(USE_STRING_BUILDER)
31
32 #if USE_STRING_BUILDER
33
34 #define FORMAT_STRING(string_builder_out, ...) sb << string_builder_out
35
36 #else  // std::snprintf
37
38 #define FORMAT_STRING(unused_string_builder_out, ...) \
39   ProcessResult(buffer,                               \
40                 &bytes,                               \
41                 sizeof(buffer) - bytes,               \
42                 std::snprintf(buffer, sizeof(buffer) - bytes, __VA_ARGS__))
43
44 #endif  // USE_STRING_BUILDER
45
46 bool ProcessResult(char* buffer, unsigned* total, unsigned size, int result) {
47   if (result < 0) {
48     // Null-terminate since snprintf doesn't report the written count.
49     buffer[size] = '\0';
50     return false;
51   }
52
53   if (static_cast<unsigned>(result) >= size) {
54     if (size > 0u) {
55       *total += size - 1;
56     }
57     return false;
58   }
59
60   *total += result;
61   return true;
62 }
63
64 volatile bool get_boolean;
65 volatile int get_integer;
66 char* volatile get_buffer;
67 char* volatile get_string;
68
69 int main() {
70   int integer = get_integer;
71   bool boolean = get_boolean;
72   auto string = get_string;
73
74   char* buffer = get_buffer;
75   unsigned size = get_integer;
76
77   unsigned bytes = 0;
78
79   // Use std::snprintf and pw::StringBuilder so they're both accounted for in
80   // the base.
81   int result = std::snprintf(buffer,
82                              size,
83                              "Hello, %s. The answer to 3 == %d is %s.",
84                              string,
85                              integer,
86                              boolean ? "true" : "false");
87
88   ProcessResult(buffer, &bytes, size, result);
89
90   pw::StringBuilder sb(std::span(buffer, size));
91   sb << "This is part of the base " << 123 << false << '\n';
92
93   sb.clear();
94
95   // Add five strings with either StringBuilder or std::snprintf.
96   FORMAT_STRING("Three", "Three");
97   FORMAT_STRING("point " << 1, "Three point %d", 1);
98   FORMAT_STRING("four "
99                     << "one" << ' ' << 5u,
100                 "four %s %u",
101                 "one",
102                 5u);
103   FORMAT_STRING(string, "%s", string);
104   FORMAT_STRING("-->" << string << string << string << ' ' << integer << ' '
105                       << boolean << '!',
106                 "--> %s%s%s %d %d!",
107                 string,
108                 string,
109                 string,
110                 integer,
111                 boolean);
112
113   // Add five more strings with either StringBuilder or std::snprintf.
114   FORMAT_STRING("Three", "Three");
115   FORMAT_STRING("point " << 1, "Three point %d", 1);
116   FORMAT_STRING("four "
117                     << "one" << ' ' << 5u,
118                 "four %s %u",
119                 "one",
120                 5u);
121   FORMAT_STRING(string, "%s", string);
122   FORMAT_STRING(string << string << string << ' ' << integer << ' ' << boolean,
123                 "%s%s%s %d %d",
124                 string,
125                 string,
126                 string,
127                 integer,
128                 boolean);
129
130   bytes += sb.size();
131   return bytes;
132 }