From 87a4c07856e7dc69958019d47b2f02ae47746ec0 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 25 Jun 2018 09:18:19 -0700 Subject: Export of internal Abseil changes. -- 8becce38c862a044db194a9aea1b505796a46d6f by Abseil Team : Updates the FixedArray's constructors to be exception safe by preventing double deletions. Also adds exception safety tests for FixedArray to document/enforce the expected behavior. PiperOrigin-RevId: 201964431 -- 794188b401a602b4be97190fb8738066fe1f9ca5 by Derek Mauro : Fixes for str_format.h documentation. PiperOrigin-RevId: 201951760 -- beae3bdd6eee2cf61101102fddc35ada188f330b by Alex Strelnikov : Add numeric_limits specialization for uint128. Turns out numeric_limits is a case where the consensus is that it is okay to specialize for a user defined type. PiperOrigin-RevId: 201944736 -- b2b3444a52b36878ade1ae8801e69932b05fc4f9 by Shaindel Schwartz : Internal change. PiperOrigin-RevId: 201718662 -- aa924c459922f39caabfc193998c58d0f4981ac0 by Abseil Team : Typo fix. PiperOrigin-RevId: 201692176 -- bbfcaa7b1af331d9b97c92470608240c5c864fbc by Xiaoyi Zhang : Use ABSL_HAVE_ANY/OPTIONAL/VARIANT to conditionally compile out the definition of absl::bad_any_cast, absl::bad_optional_access, absl::bad_variant_access. This would fix the issues where users #include those header directly in C++17 modes. PiperOrigin-RevId: 201683792 GitOrigin-RevId: 8becce38c862a044db194a9aea1b505796a46d6f Change-Id: I60a7ad043136a439d82c374d225a1804016b0509 --- absl/container/fixed_array.h | 52 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 29 deletions(-) (limited to 'absl/container/fixed_array.h') diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 06bc8009..295f0108 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -108,33 +108,46 @@ class FixedArray { ? kInlineBytesDefault / sizeof(value_type) : inlined; - FixedArray(const FixedArray& other) : rep_(other.begin(), other.end()) {} + FixedArray(const FixedArray& other) + : FixedArray(other.begin(), other.end()) {} + FixedArray(FixedArray&& other) noexcept( // clang-format off absl::allocator_is_nothrow>::value && // clang-format on std::is_nothrow_move_constructible::value) - : rep_(std::make_move_iterator(other.begin()), - std::make_move_iterator(other.end())) {} + : FixedArray(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end())) {} // Creates an array object that can store `n` elements. // Note that trivially constructible elements will be uninitialized. - explicit FixedArray(size_type n) : rep_(n) {} + explicit FixedArray(size_type n) : rep_(n) { + absl::memory_internal::uninitialized_default_construct_n(rep_.begin(), + size()); + } // Creates an array initialized with `n` copies of `val`. - FixedArray(size_type n, const value_type& val) : rep_(n, val) {} + FixedArray(size_type n, const value_type& val) : rep_(n) { + std::uninitialized_fill_n(data(), size(), val); + } // Creates an array initialized with the elements from the input // range. The array's size will always be `std::distance(first, last)`. // REQUIRES: Iter must be a forward_iterator or better. template = 0> - FixedArray(Iter first, Iter last) : rep_(first, last) {} + FixedArray(Iter first, Iter last) : rep_(std::distance(first, last)) { + std::uninitialized_copy(first, last, data()); + } // Creates the array from an initializer_list. FixedArray(std::initializer_list init_list) : FixedArray(init_list.begin(), init_list.end()) {} - ~FixedArray() {} + ~FixedArray() noexcept { + for (Holder* cur = rep_.begin(); cur != rep_.end(); ++cur) { + cur->~Holder(); + } + } // Assignments are deleted because they break the invariant that the size of a // `FixedArray` never changes. @@ -431,32 +444,13 @@ class FixedArray { // Rep // - // A const Rep object holds FixedArray's size and data pointer. + // An instance of Rep manages the inline and out-of-line memory for FixedArray // class Rep : public InlineSpace { public: - Rep(size_type n, const value_type& val) : n_(n), p_(MakeHolder(n)) { - std::uninitialized_fill_n(p_, n, val); - } - - explicit Rep(size_type n) : n_(n), p_(MakeHolder(n)) { - // Loop optimizes to nothing for trivially constructible T. - for (Holder* p = p_; p != p_ + n; ++p) - // Note: no parens: default init only. - // Also note '::' to avoid Holder class placement new operator. - ::new (static_cast(p)) Holder; - } - - template - Rep(Iter first, Iter last) - : n_(std::distance(first, last)), p_(MakeHolder(n_)) { - std::uninitialized_copy(first, last, AsValue(p_)); - } + explicit Rep(size_type n) : n_(n), p_(MakeHolder(n)) {} - ~Rep() { - // Destruction must be in reverse order. - // Loop optimizes to nothing for trivially destructible T. - for (Holder* p = end(); p != begin();) (--p)->~Holder(); + ~Rep() noexcept { if (IsAllocated(size())) { std::allocator().deallocate(p_, n_); } else { -- cgit v1.2.3