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;