gfe-relnote: (n/a) Make QuicCircularDeque compile in Chromium. Code not used yet. QuicCircularDeque uses some c++17 features(if constexpr, some type traits) which are not available in Chromium, this cl changes them to compile under c++14. PiperOrigin-RevId: 278849141 Change-Id: I27eef9303ac07889ab3504776ab2511ceb82127f
diff --git a/quic/core/quic_circular_deque.h b/quic/core/quic_circular_deque.h index 398448f..54043fd 100644 --- a/quic/core/quic_circular_deque.h +++ b/quic/core/quic_circular_deque.h
@@ -10,6 +10,7 @@ #include <iterator> #include <memory> #include <ostream> +#include <type_traits> #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" @@ -206,10 +207,11 @@ resize(count); } - template <class InputIt, - typename = std::enable_if_t<std::is_base_of_v< - std::input_iterator_tag, - typename std::iterator_traits<InputIt>::iterator_category>>> + template < + class InputIt, + typename = std::enable_if_t<std::is_base_of< + std::input_iterator_tag, + typename std::iterator_traits<InputIt>::iterator_category>::value>> QuicCircularDeque(InputIt first, InputIt last, const Allocator& alloc = allocator_type()) @@ -288,10 +290,11 @@ } } - template <class InputIt, - typename = std::enable_if_t<std::is_base_of_v< - std::input_iterator_tag, - typename std::iterator_traits<InputIt>::iterator_category>>> + template < + class InputIt, + typename = std::enable_if_t<std::is_base_of< + std::input_iterator_tag, + typename std::iterator_traits<InputIt>::iterator_category>::value>> void assign(InputIt first, InputIt last) { AssignRange(first, last); } @@ -495,15 +498,16 @@ } } - template <typename InputIt, - typename = std::enable_if_t<std::is_base_of_v< - std::input_iterator_tag, - typename std::iterator_traits<InputIt>::iterator_category>>> + template < + typename InputIt, + typename = std::enable_if_t<std::is_base_of< + std::input_iterator_tag, + typename std::iterator_traits<InputIt>::iterator_category>::value>> void AssignRange(InputIt first, InputIt last) { ClearRetainCapacity(); - if constexpr (std::is_base_of_v<std::random_access_iterator_tag, - typename std::iterator_traits< - InputIt>::iterator_category>) { + if (std::is_base_of< + std::random_access_iterator_tag, + typename std::iterator_traits<InputIt>::iterator_category>::value) { reserve(std::distance(first, last)); } for (; first != last; ++first) { @@ -576,26 +580,43 @@ end_ = num_elements; } - void RelocateUnwrappedRange(size_type begin, - size_type end, - pointer dest) const { + template <typename T_ = T> + typename std::enable_if<std::is_trivially_copyable<T_>::value, void>::type + RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const { DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end; - if constexpr (std::is_trivially_copyable_v<T>) { - memcpy(dest, index_to_address(begin), sizeof(T) * (end - begin)); - DestroyRange(begin, end); - } else { - pointer src = index_to_address(begin); - pointer src_end = index_to_address(end); - while (src != src_end) { - if constexpr (std::is_move_constructible_v<T>) { - new (dest) T(std::move(*src)); - } else { - new (dest) T(*src); - } - DestroyByAddress(src); - ++dest; - ++src; - } + memcpy(dest, index_to_address(begin), sizeof(T) * (end - begin)); + DestroyRange(begin, end); + } + + template <typename T_ = T> + typename std::enable_if<!std::is_trivially_copyable<T_>::value && + std::is_move_constructible<T_>::value, + void>::type + RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const { + DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end; + pointer src = index_to_address(begin); + pointer src_end = index_to_address(end); + while (src != src_end) { + new (dest) T(std::move(*src)); + DestroyByAddress(src); + ++dest; + ++src; + } + } + + template <typename T_ = T> + typename std::enable_if<!std::is_trivially_copyable<T_>::value && + !std::is_move_constructible<T_>::value, + void>::type + RelocateUnwrappedRange(size_type begin, size_type end, pointer dest) const { + DCHECK_LE(begin, end) << "begin:" << begin << ", end:" << end; + pointer src = index_to_address(begin); + pointer src_end = index_to_address(end); + while (src != src_end) { + new (dest) T(*src); + DestroyByAddress(src); + ++dest; + ++src; } } @@ -618,7 +639,7 @@ } void DestroyRange(size_type begin, size_type end) const { - if constexpr (std::is_trivially_destructible_v<T>) { + if (std::is_trivially_destructible<T>::value) { return; } if (end >= begin) { @@ -642,7 +663,7 @@ } void DestroyByAddress(pointer address) const { - if constexpr (std::is_trivially_destructible_v<T>) { + if (std::is_trivially_destructible<T>::value) { return; } address->~T();
diff --git a/quic/core/quic_circular_deque_test.cc b/quic/core/quic_circular_deque_test.cc index 19f8ca2..f9774ee 100644 --- a/quic/core/quic_circular_deque_test.cc +++ b/quic/core/quic_circular_deque_test.cc
@@ -197,7 +197,7 @@ EXPECT_LT(1u, dq3.get_allocator().allocate_count()); // Copy assignment - dq3 = dq3; + dq3 = *&dq3; EXPECT_THAT(dq3, ElementsAre(3, 3, 3, 3, 3)); QuicCircularDeque< @@ -580,8 +580,8 @@ { // Move construct in Relocate. typedef std::unique_ptr<Foo> MoveConstructible; - ASSERT_FALSE(std::is_trivially_copyable_v<MoveConstructible>); - ASSERT_TRUE(std::is_move_constructible_v<MoveConstructible>); + ASSERT_FALSE(std::is_trivially_copyable<MoveConstructible>::value); + ASSERT_TRUE(std::is_move_constructible<MoveConstructible>::value); QuicCircularDeque<MoveConstructible, 3, CountingAllocator<MoveConstructible>> dq1; @@ -601,8 +601,8 @@ { // Copy construct in Relocate. typedef Foo NonMoveConstructible; - ASSERT_FALSE(std::is_trivially_copyable_v<NonMoveConstructible>); - ASSERT_FALSE(std::is_move_constructible_v<NonMoveConstructible>); + ASSERT_FALSE(std::is_trivially_copyable<NonMoveConstructible>::value); + ASSERT_FALSE(std::is_move_constructible<NonMoveConstructible>::value); QuicCircularDeque<NonMoveConstructible, 3, CountingAllocator<NonMoveConstructible>> dq2;