From 02451914b9ad5320f81f56a89f3eef1f8683227c Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 11 Sep 2018 11:22:56 -0700 Subject: [PATCH] Export of internal Abseil changes. -- 74c1330e29f1501f2738258faf9ec4564395c90a by Gennadiy Civil : Merging https://github.com/abseil/abseil-cpp/pull/166 PiperOrigin-RevId: 212487256 -- 4ac236574ff8fb3cc1125505292b0bd8c8192da9 by Abseil Team : Allow c_move to take rvalue containers. PiperOrigin-RevId: 212458618 -- ce94e23984870db666d4c91623ae45b3c60b5b61 by Matt Armstrong : Internal change. PiperOrigin-RevId: 212153041 -- 7d88d286821c5839934756dd63a704ed162c49cb by Chris Kennelly : Internal change PiperOrigin-RevId: 211982309 -- ddae814b3f609948c20551ea3d80bf51b973f480 by Abseil Team : Remove unused argument from InlinedVector's AllocatorAndTag This is not part of InlinedVector's public interface. PiperOrigin-RevId: 211973017 -- 051fbfd81648a8da66c62c6603af63038d709c15 by Abseil Team : Minor performance fix PiperOrigin-RevId: 211820453 -- c205cb2add7400bc8caf2131cb700eea560b7dbf by Laramie Leavitt : Make absl::Span a tiny bit more consistent. Add constexper to equivalent absl::Span members as described by http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0122r7.pdf * Span constructor use consistently delegate to Span(ptr, length) * Mark more member methods as constexpr. * Use data() and size() consistently in member methods. PiperOrigin-RevId: 211707244 -- 55500c9e941f2f58f4a95c121f32772408866eee by Derek Mauro : Stop catching polymorphic exception types by value. GCC 8 emits a warning for this. PiperOrigin-RevId: 211684466 GitOrigin-RevId: 74c1330e29f1501f2738258faf9ec4564395c90a Change-Id: Iceab4a5b30ee35d82ef494830262ad29c028cb0a --- absl/algorithm/container.h | 2 +- absl/algorithm/container_test.cc | 15 +++++++ absl/base/exception_safety_testing_test.cc | 2 +- absl/base/internal/exception_safety_testing.h | 2 +- absl/container/inlined_vector.h | 3 +- absl/strings/internal/str_format/bind.cc | 41 +++++++++--------- absl/strings/internal/str_format/bind.h | 32 ++++++++------ absl/types/any_exception_safety_test.cc | 2 +- absl/types/optional_exception_safety_test.cc | 2 +- absl/types/span.h | 42 +++++++++++-------- absl/types/variant_exception_safety_test.cc | 4 +- 11 files changed, 86 insertions(+), 61 deletions(-) diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 6af8c0979..53ab15686 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 `std::move()` function to move // a container's elements into an iterator. template -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 de66f1468..1502b17f8 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> src; + src.emplace_back(absl::make_unique(1)); + src.emplace_back(absl::make_unique(2)); + src.emplace_back(absl::make_unique(3)); + return src; + }; + + std::vector> 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 odds = {2, 4, 6}; std::vector evens = {1, 3, 5}; diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index c2922f33c..9141e39c7 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -38,7 +38,7 @@ template 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 8c2f5093f..de4f0e282 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 ca36fd369..0c0ffb0b1 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 33e864155..c4eddd17d 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -103,15 +103,15 @@ class ConverterConsumer { }; template -bool ConvertAll(const UntypedFormatSpecImpl& format, - absl::Span args, - const Converter& converter) { - const ParsedFormatBase* pc = format.parsed_conversion(); - if (pc) - return pc->ProcessFormat(ConverterConsumer(converter, args)); - - return ParseFormatString(format.str(), - ConverterConsumer(converter, args)); +bool ConvertAll(const UntypedFormatSpecImpl format, + absl::Span args, Converter converter) { + if (format.has_parsed_conversion()) { + return format.parsed_conversion()->ProcessFormat( + ConverterConsumer(converter, args)); + } else { + return ParseFormatString(format.str(), + ConverterConsumer(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 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 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 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 args) { FILERawSink sink(output); if (!FormatUntyped(&sink, format, args)) { @@ -216,7 +213,7 @@ int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, return static_cast(sink.count()); } -int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, +int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format, absl::Span 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 9d3d67c63..a503b19bb 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(data_), size_); + } const str_format_internal::ParsedFormatBase* parsed_conversion() const { - return pc_; + assert(has_parsed_conversion()); + return static_cast(data_); } template @@ -48,8 +56,8 @@ class UntypedFormatSpecImpl { } private: - string_view str_; - const str_format_internal::ParsedFormatBase* pc_; + const void* data_; + size_t size_; }; template @@ -144,28 +152,28 @@ class Streamable { }; // for testing -std::string Summarize(const UntypedFormatSpecImpl& format, +std::string Summarize(UntypedFormatSpecImpl format, absl::Span args); bool BindWithPack(const UnboundConversion* props, absl::Span pack, BoundConversion* bound); bool FormatUntyped(FormatRawSinkImpl raw_sink, - const UntypedFormatSpecImpl& format, + UntypedFormatSpecImpl format, absl::Span args); -std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl& format, +std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format, absl::Span args); -inline std::string FormatPack(const UntypedFormatSpecImpl& format, +inline std::string FormatPack(const UntypedFormatSpecImpl format, absl::Span 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 args); -int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, +int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format, absl::Span 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 36955f6c5..cfb82d804 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(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 d2ef04b8d..31eb66df5 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 bool ValueThrowsBadOptionalAccess(const OptionalT& optional) try { return (static_cast(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 5387e8e02..3359ce509 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 27c0b96ca..a3c9eac33 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(); v.emplace(ExceptionOnConversion()); - } catch (ConversionException& /*e*/) { + } catch (const ConversionException&) { // This space intentionally left blank. } } @@ -100,7 +100,7 @@ testing::AssertionResult CheckInvariants(ThrowingVariant* v) { auto unused = absl::get(*v); static_cast(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"; }