diff options
author | Abseil Team <absl-team@google.com> | 2018-04-23T22·50-0700 |
---|---|---|
committer | Derek Mauro <dmauro@google.com> | 2018-04-24T14·09-0400 |
commit | 19b3c95727316cef3b0b40eaf37f6645a876f8d2 (patch) | |
tree | 093012eb09e5d01e98c941607a884dd79d0db55b /absl/strings/substitute.cc | |
parent | af7882601aad93ada881486eeaabc562f1733961 (diff) |
- 3a9532fb2d6ae45c3cba44c9bb0dbdfc1558b7d3 Fix the description of Span::subspan(). by Abseil Team <absl-team@google.com>
- bae1a1c21924bd31fa7315eff05ea6158d9e7947 Port the symbolizer to Windows. by Derek Mauro <dmauro@google.com> - 2253c04c1a4f39d9581772f1dc4491878aa3831f Support absl::Hex() and absl::Dec() as arguments to absl:... by Jorg Brown <jorg@google.com> - 552c3ac259e9c254fda9244755487f3423d2fe4b Internal change by Jorg Brown <jorg@google.com> GitOrigin-RevId: 3a9532fb2d6ae45c3cba44c9bb0dbdfc1558b7d3 Change-Id: I448133c9bb6d837037c12b45a9a16a7945049453
Diffstat (limited to 'absl/strings/substitute.cc')
-rw-r--r-- | absl/strings/substitute.cc | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/absl/strings/substitute.cc b/absl/strings/substitute.cc index f739f8c20b2c..3b2005945095 100644 --- a/absl/strings/substitute.cc +++ b/absl/strings/substitute.cc @@ -94,6 +94,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, assert(target == output->data() + output->size()); } +static const char kHexDigits[] = "0123456789abcdef"; Arg::Arg(const void* value) { static_assert(sizeof(scratch_) >= sizeof(value) * 2 + 2, "fix sizeof(scratch_)"); @@ -102,7 +103,6 @@ Arg::Arg(const void* value) { } else { char* ptr = scratch_ + sizeof(scratch_); uintptr_t num = reinterpret_cast<uintptr_t>(value); - static const char kHexDigits[] = "0123456789abcdef"; do { *--ptr = kHexDigits[num & 0xf]; num >>= 4; @@ -113,5 +113,58 @@ Arg::Arg(const void* value) { } } +// TODO(jorg): Don't duplicate so much code between here and str_cat.cc +Arg::Arg(Hex hex) { + char* const end = &scratch_[numbers_internal::kFastToBufferSize]; + char* writer = end; + uint64_t value = hex.value; + do { + *--writer = kHexDigits[value & 0xF]; + value >>= 4; + } while (value != 0); + + char* beg; + if (end - writer < hex.width) { + beg = end - hex.width; + std::fill_n(beg, writer - beg, hex.fill); + } else { + beg = writer; + } + + piece_ = absl::string_view(beg, end - beg); +} + +// TODO(jorg): Don't duplicate so much code between here and str_cat.cc +Arg::Arg(Dec dec) { + assert(dec.width <= numbers_internal::kFastToBufferSize); + char* const end = &scratch_[numbers_internal::kFastToBufferSize]; + char* const minfill = end - dec.width; + char* writer = end; + uint64_t value = dec.value; + bool neg = dec.neg; + while (value > 9) { + *--writer = '0' + (value % 10); + value /= 10; + } + *--writer = '0' + value; + if (neg) *--writer = '-'; + + ptrdiff_t fillers = writer - minfill; + if (fillers > 0) { + // Tricky: if the fill character is ' ', then it's <fill><+/-><digits> + // But...: if the fill character is '0', then it's <+/-><fill><digits> + bool add_sign_again = false; + if (neg && dec.fill == '0') { // If filling with '0', + ++writer; // ignore the sign we just added + add_sign_again = true; // and re-add the sign later. + } + writer -= fillers; + std::fill_n(writer, fillers, dec.fill); + if (add_sign_again) *--writer = '-'; + } + + piece_ = absl::string_view(writer, end - writer); +} + } // namespace substitute_internal } // namespace absl |