about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--absl/algorithm/container.h2
-rw-r--r--absl/algorithm/container_test.cc15
-rw-r--r--absl/base/exception_safety_testing_test.cc2
-rw-r--r--absl/base/internal/exception_safety_testing.h2
-rw-r--r--absl/container/inlined_vector.h3
-rw-r--r--absl/strings/internal/str_format/bind.cc41
-rw-r--r--absl/strings/internal/str_format/bind.h32
-rw-r--r--absl/types/any_exception_safety_test.cc2
-rw-r--r--absl/types/optional_exception_safety_test.cc2
-rw-r--r--absl/types/span.h42
-rw-r--r--absl/types/variant_exception_safety_test.cc4
11 files changed, 86 insertions, 61 deletions
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index 6af8c09799e5..53ab15686c6e 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -494,7 +494,7 @@ BidirectionalIterator c_copy_backward(const C& src,
 // Container-based version of the <algorithm> `std::move()` function to move
 // a container's elements into an iterator.
 template <typename C, typename OutputIterator>
-OutputIterator c_move(C& src, OutputIterator dest) {
+OutputIterator c_move(C&& src, OutputIterator dest) {
   return std::move(container_algorithm_internal::c_begin(src),
                    container_algorithm_internal::c_end(src), dest);
 }
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc
index de66f14680f1..1502b17f8636 100644
--- a/absl/algorithm/container_test.cc
+++ b/absl/algorithm/container_test.cc
@@ -636,6 +636,21 @@ TEST(MutatingTest, Move) {
                                 Pointee(5)));
 }
 
+TEST(MutatingTest, MoveWithRvalue) {
+  auto MakeRValueSrc = [] {
+    std::vector<std::unique_ptr<int>> src;
+    src.emplace_back(absl::make_unique<int>(1));
+    src.emplace_back(absl::make_unique<int>(2));
+    src.emplace_back(absl::make_unique<int>(3));
+    return src;
+  };
+
+  std::vector<std::unique_ptr<int>> dest = MakeRValueSrc();
+  absl::c_move(MakeRValueSrc(), std::back_inserter(dest));
+  EXPECT_THAT(dest, ElementsAre(Pointee(1), Pointee(2), Pointee(3), Pointee(1),
+                                Pointee(2), Pointee(3)));
+}
+
 TEST(MutatingTest, SwapRanges) {
   std::vector<int> odds = {2, 4, 6};
   std::vector<int> evens = {1, 3, 5};
diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc
index c2922f33c66b..9141e39c796b 100644
--- a/absl/base/exception_safety_testing_test.cc
+++ b/absl/base/exception_safety_testing_test.cc
@@ -38,7 +38,7 @@ template <typename F>
 void ExpectNoThrow(const F& f) {
   try {
     f();
-  } catch (TestException e) {
+  } catch (const TestException& e) {
     ADD_FAILURE() << "Unexpected exception thrown from " << e.what();
   }
 }
diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h
index 8c2f5093fc4d..de4f0e2827cb 100644
--- a/absl/base/internal/exception_safety_testing.h
+++ b/absl/base/internal/exception_safety_testing.h
@@ -858,7 +858,7 @@ testing::AssertionResult TestNothrowOp(const Operation& operation) {
   try {
     operation();
     return testing::AssertionSuccess();
-  } catch (exceptions_internal::TestException) {
+  } catch (const exceptions_internal::TestException&) {
     return testing::AssertionFailure()
            << "TestException thrown during call to operation() when nothrow "
               "guarantee was expected.";
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index ca36fd3699b9..0c0ffb0b1366 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -648,8 +648,7 @@ class InlinedVector {
   // our instance of it for free.
   class AllocatorAndTag : private allocator_type {
    public:
-    explicit AllocatorAndTag(const allocator_type& a, Tag t = Tag())
-        : allocator_type(a), tag_(t) {}
+    explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {}
     Tag& tag() { return tag_; }
     const Tag& tag() const { return tag_; }
     allocator_type& allocator() { return *this; }
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc
index 33e8641558ab..c4eddd17ddbe 100644
--- a/absl/strings/internal/str_format/bind.cc
+++ b/absl/strings/internal/str_format/bind.cc
@@ -103,15 +103,15 @@ class ConverterConsumer {
 };
 
 template <typename Converter>
-bool ConvertAll(const UntypedFormatSpecImpl& format,
-                absl::Span<const FormatArgImpl> args,
-                const Converter& converter) {
-  const ParsedFormatBase* pc = format.parsed_conversion();
-  if (pc)
-    return pc->ProcessFormat(ConverterConsumer<Converter>(converter, args));
-
-  return ParseFormatString(format.str(),
-                           ConverterConsumer<Converter>(converter, args));
+bool ConvertAll(const UntypedFormatSpecImpl format,
+                absl::Span<const FormatArgImpl> args, Converter converter) {
+  if (format.has_parsed_conversion()) {
+    return format.parsed_conversion()->ProcessFormat(
+        ConverterConsumer<Converter>(converter, args));
+  } else {
+    return ParseFormatString(format.str(),
+                             ConverterConsumer<Converter>(converter, args));
+  }
 }
 
 class DefaultConverter {
@@ -158,7 +158,7 @@ bool BindWithPack(const UnboundConversion* props,
   return ArgContext(pack).Bind(props, bound);
 }
 
-std::string Summarize(const UntypedFormatSpecImpl& format,
+std::string Summarize(const UntypedFormatSpecImpl format,
                  absl::Span<const FormatArgImpl> args) {
   typedef SummarizingConverter Converter;
   std::string out;
@@ -167,23 +167,18 @@ std::string Summarize(const UntypedFormatSpecImpl& format,
     // flush.
     FormatSinkImpl sink(&out);
     if (!ConvertAll(format, args, Converter(&sink))) {
-      sink.Flush();
-      out.clear();
+      return "";
     }
   }
   return out;
 }
 
 bool FormatUntyped(FormatRawSinkImpl raw_sink,
-                   const UntypedFormatSpecImpl& format,
+                   const UntypedFormatSpecImpl format,
                    absl::Span<const FormatArgImpl> args) {
   FormatSinkImpl sink(raw_sink);
   using Converter = DefaultConverter;
-  if (!ConvertAll(format, args, Converter(&sink))) {
-    sink.Flush();
-    return false;
-  }
-  return true;
+  return ConvertAll(format, args, Converter(&sink));
 }
 
 std::ostream& Streamable::Print(std::ostream& os) const {
@@ -191,14 +186,16 @@ std::ostream& Streamable::Print(std::ostream& os) const {
   return os;
 }
 
-std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format,
+std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format,
                    absl::Span<const FormatArgImpl> args) {
   size_t orig = out->size();
-  if (!FormatUntyped(out, format, args)) out->resize(orig);
+  if (ABSL_PREDICT_FALSE(!FormatUntyped(out, format, args))) {
+    out->erase(orig);
+  }
   return *out;
 }
 
-int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format,
+int FprintF(std::FILE* output, const UntypedFormatSpecImpl format,
             absl::Span<const FormatArgImpl> args) {
   FILERawSink sink(output);
   if (!FormatUntyped(&sink, format, args)) {
@@ -216,7 +213,7 @@ int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format,
   return static_cast<int>(sink.count());
 }
 
-int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format,
+int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format,
              absl::Span<const FormatArgImpl> args) {
   BufferRawSink sink(output, size ? size - 1 : 0);
   if (!FormatUntyped(&sink, format, args)) {
diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h
index 9d3d67c63470..a503b19bb675 100644
--- a/absl/strings/internal/str_format/bind.h
+++ b/absl/strings/internal/str_format/bind.h
@@ -33,13 +33,21 @@ class UntypedFormatSpecImpl {
  public:
   UntypedFormatSpecImpl() = delete;
 
-  explicit UntypedFormatSpecImpl(string_view s) : str_(s), pc_() {}
+  explicit UntypedFormatSpecImpl(string_view s)
+      : data_(s.data()), size_(s.size()) {}
   explicit UntypedFormatSpecImpl(
       const str_format_internal::ParsedFormatBase* pc)
-      : pc_(pc) {}
-  string_view str() const { return str_; }
+      : data_(pc), size_(~size_t{}) {}
+
+  bool has_parsed_conversion() const { return size_ == ~size_t{}; }
+
+  string_view str() const {
+    assert(!has_parsed_conversion());
+    return string_view(static_cast<const char*>(data_), size_);
+  }
   const str_format_internal::ParsedFormatBase* parsed_conversion() const {
-    return pc_;
+    assert(has_parsed_conversion());
+    return static_cast<const str_format_internal::ParsedFormatBase*>(data_);
   }
 
   template <typename T>
@@ -48,8 +56,8 @@ class UntypedFormatSpecImpl {
   }
 
  private:
-  string_view str_;
-  const str_format_internal::ParsedFormatBase* pc_;
+  const void* data_;
+  size_t size_;
 };
 
 template <typename T, typename...>
@@ -144,28 +152,28 @@ class Streamable {
 };
 
 // for testing
-std::string Summarize(const UntypedFormatSpecImpl& format,
+std::string Summarize(UntypedFormatSpecImpl format,
                  absl::Span<const FormatArgImpl> args);
 bool BindWithPack(const UnboundConversion* props,
                   absl::Span<const FormatArgImpl> pack, BoundConversion* bound);
 
 bool FormatUntyped(FormatRawSinkImpl raw_sink,
-                   const UntypedFormatSpecImpl& format,
+                   UntypedFormatSpecImpl format,
                    absl::Span<const FormatArgImpl> args);
 
-std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format,
+std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
                    absl::Span<const FormatArgImpl> args);
 
-inline std::string FormatPack(const UntypedFormatSpecImpl& format,
+inline std::string FormatPack(const UntypedFormatSpecImpl format,
                          absl::Span<const FormatArgImpl> args) {
   std::string out;
   AppendPack(&out, format, args);
   return out;
 }
 
-int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format,
+int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
             absl::Span<const FormatArgImpl> args);
-int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format,
+int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format,
              absl::Span<const FormatArgImpl> args);
 
 // Returned by Streamed(v). Converts via '%s' to the string created
diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc
index 36955f6c5c37..cfb82d80445c 100644
--- a/absl/types/any_exception_safety_test.cc
+++ b/absl/types/any_exception_safety_test.cc
@@ -62,7 +62,7 @@ testing::AssertionResult AnyInvariants(absl::any* a) {
     static_cast<void>(unused);
     return AssertionFailure()
            << "A reset `any` should not be able to be any_cast";
-  } catch (absl::bad_any_cast) {
+  } catch (const absl::bad_any_cast&) {
   } catch (...) {
     return AssertionFailure()
            << "Unexpected exception thrown from absl::any_cast";
diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc
index d2ef04b8d1b0..31eb66df5445 100644
--- a/absl/types/optional_exception_safety_test.cc
+++ b/absl/types/optional_exception_safety_test.cc
@@ -38,7 +38,7 @@ constexpr int kUpdatedInteger = 10;
 template <typename OptionalT>
 bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try {
   return (static_cast<void>(optional.value()), false);
-} catch (absl::bad_optional_access) {
+} catch (const absl::bad_optional_access&) {
   return true;
 }
 
diff --git a/absl/types/span.h b/absl/types/span.h
index 5387e8e027df..3359ce5093c5 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -379,64 +379,70 @@ class Span {
   //
   // Returns a reference to the i'th element of this span.
   constexpr reference at(size_type i) const {
-    return ABSL_PREDICT_TRUE(i < size())
-               ? ptr_[i]
+    return ABSL_PREDICT_TRUE(i < size())  //
+               ? *(data() + i)
                : (base_internal::ThrowStdOutOfRange(
                       "Span::at failed bounds check"),
-                  ptr_[i]);
+                  *(data() + i));
   }
 
   // Span::front()
   //
   // Returns a reference to the first element of this span.
-  reference front() const noexcept { return ABSL_ASSERT(size() > 0), ptr_[0]; }
+  constexpr reference front() const noexcept {
+    return ABSL_ASSERT(size() > 0), *data();
+  }
 
   // Span::back()
   //
   // Returns a reference to the last element of this span.
-  reference back() const noexcept {
-    return ABSL_ASSERT(size() > 0), ptr_[size() - 1];
+  constexpr reference back() const noexcept {
+    return ABSL_ASSERT(size() > 0), *(data() + size() - 1);
   }
 
   // Span::begin()
   //
   // Returns an iterator to the first element of this span.
-  constexpr iterator begin() const noexcept { return ptr_; }
+  constexpr iterator begin() const noexcept { return data(); }
 
   // Span::cbegin()
   //
   // Returns a const iterator to the first element of this span.
-  constexpr const_iterator cbegin() const noexcept { return ptr_; }
+  constexpr const_iterator cbegin() const noexcept { return begin(); }
 
   // Span::end()
   //
   // Returns an iterator to the last element of this span.
-  iterator end() const noexcept { return ptr_ + len_; }
+  constexpr iterator end() const noexcept { return data() + size(); }
 
   // Span::cend()
   //
   // Returns a const iterator to the last element of this span.
-  const_iterator cend() const noexcept { return end(); }
+  constexpr const_iterator cend() const noexcept { return end(); }
 
   // Span::rbegin()
   //
   // Returns a reverse iterator starting at the last element of this span.
-  reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
+  constexpr reverse_iterator rbegin() const noexcept {
+    return reverse_iterator(end());
+  }
 
   // Span::crbegin()
   //
   // Returns a reverse const iterator starting at the last element of this span.
-  const_reverse_iterator crbegin() const noexcept { return rbegin(); }
+  constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
 
   // Span::rend()
   //
   // Returns a reverse iterator starting at the first element of this span.
-  reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
+  constexpr reverse_iterator rend() const noexcept {
+    return reverse_iterator(begin());
+  }
 
   // Span::crend()
   //
   // Returns a reverse iterator starting at the first element of this span.
-  const_reverse_iterator crend() const noexcept { return rend(); }
+  constexpr const_reverse_iterator crend() const noexcept { return rend(); }
 
   // Span mutations
 
@@ -444,7 +450,7 @@ class Span {
   //
   // Removes the first `n` elements from the span.
   void remove_prefix(size_type n) noexcept {
-    assert(len_ >= n);
+    assert(size() >= n);
     ptr_ += n;
     len_ -= n;
   }
@@ -453,7 +459,7 @@ class Span {
   //
   // Removes the last `n` elements from the span.
   void remove_suffix(size_type n) noexcept {
-    assert(len_ >= n);
+    assert(size() >= n);
     len_ -= n;
   }
 
@@ -474,8 +480,8 @@ class Span {
   //   absl::MakeSpan(vec).subspan(4);     // {}
   //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
   constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
-    return (pos <= len_)
-               ? Span(ptr_ + pos, span_internal::Min(len_ - pos, len))
+    return (pos <= size())
+               ? Span(data() + pos, span_internal::Min(size() - pos, len))
                : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
   }
 
diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc
index 27c0b96ca6f3..a3c9eac33a75 100644
--- a/absl/types/variant_exception_safety_test.cc
+++ b/absl/types/variant_exception_safety_test.cc
@@ -53,7 +53,7 @@ void ToValuelessByException(ThrowingVariant& v) {  // NOLINT
   try {
     v.emplace<Thrower>();
     v.emplace<Thrower>(ExceptionOnConversion<Thrower>());
-  } catch (ConversionException& /*e*/) {
+  } catch (const ConversionException&) {
     // This space intentionally left blank.
   }
 }
@@ -100,7 +100,7 @@ testing::AssertionResult CheckInvariants(ThrowingVariant* v) {
     auto unused = absl::get<Thrower>(*v);
     static_cast<void>(unused);
     return AssertionFailure() << "Variant should not contain Thrower";
-  } catch (absl::bad_variant_access) {
+  } catch (const absl::bad_variant_access&) {
   } catch (...) {
     return AssertionFailure() << "Unexpected exception throw from absl::get";
   }