Skip to content

Commit 0d58f9d

Browse files
Googlera-maurice
authored andcommitted
Fix incompatibilities with older C++ compilers that don't support
std::conditional, std::next, std::prev, or std::move. Tested: blaze build --config=android_arm :app_kokoro blaze test :cpp11_thread_test :pthread_thread_test :future_test \ :future_manager_test :intrusive_list_test PiperOrigin-RevId: 269682693
1 parent 38bbd09 commit 0d58f9d

File tree

1 file changed

+50
-9
lines changed

1 file changed

+50
-9
lines changed

app/src/intrusive_list.h

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,43 @@
5656

5757
namespace FIREBASE_NAMESPACE {
5858

59+
namespace emulate_std {
60+
61+
// conditional<B, T1, T2>::type is T1 if B is true, or T2 if B is false.
62+
// This is the same as std::conditional<B, T1, T2>, but works with
63+
// older compilers that don't support std::conditional.
64+
65+
template <bool B, typename T1, typename T2>
66+
struct conditional;
67+
68+
template <typename T1, typename T2>
69+
struct conditional<true, T1, T2> {
70+
typedef T1 type;
71+
};
72+
73+
template <typename T1, typename T2>
74+
struct conditional<false, T1, T2> {
75+
typedef T2 type;
76+
};
77+
78+
// Same as std::prev,
79+
// but works with older compilers that don't support std::prev.
80+
template<class BidirectionalIt>
81+
BidirectionalIt prev(BidirectionalIt it) {
82+
std::advance(it, -1);
83+
return it;
84+
}
85+
86+
// Same as std::next,
87+
// but works with older compilers that don't support std::prev.
88+
template<class ForwardIt>
89+
ForwardIt next(ForwardIt it) {
90+
std::advance(it, 1);
91+
return it;
92+
}
93+
94+
} // namespace emulate_std.
95+
5996
class intrusive_list_node;
6097

6198
template <typename T>
@@ -213,13 +250,15 @@ class intrusive_list {
213250
explicit intrusive_list(intrusive_list_node T::*node_member)
214251
: data_(&data_, &data_), node_offset_(offset_of_node(node_member)) {}
215252

253+
#if defined(FIREBASE_USE_MOVE_OPERATORS)
216254
intrusive_list(this_type&& other) { *this = std::move(other); }
217255

218256
intrusive_list& operator=(this_type&& other) {
219257
data_ = std::move(other.data_);
220258
node_offset_ = std::move(other.node_offset_);
221259
return *this;
222260
}
261+
#endif
223262

224263
#if defined(_MSC_VER)
225264
// Normally we need to disallow copying. Ideally we'd put this in the
@@ -423,7 +462,7 @@ class intrusive_list {
423462
}
424463

425464
void splice(iterator pos, iterator iter) {
426-
splice(pos, iter, std::next(iter));
465+
splice(pos, iter, emulate_std::next(iter));
427466
}
428467

429468
void splice(iterator pos, iterator first, iterator last) {
@@ -473,8 +512,8 @@ class intrusive_list {
473512
return;
474513
}
475514
iterator iter = begin();
476-
while (iter != std::prev(end())) {
477-
iterator next_iter = std::next(iter);
515+
while (iter != emulate_std::prev(end())) {
516+
iterator next_iter = emulate_std::next(iter);
478517
if (pred(*iter, *next_iter)) {
479518
remove(*next_iter, node_offset_);
480519
} else {
@@ -494,9 +533,9 @@ class intrusive_list {
494533
iterator next;
495534
for (iterator i = begin(); i != end(); i = next) {
496535
// Cache the `next` node because `i` might move.
497-
next = std::next(i);
536+
next = emulate_std::next(i);
498537
iterator j = i;
499-
while (j != begin() && compare(*i, *std::prev(j))) {
538+
while (j != begin() && compare(*i, *emulate_std::prev(j))) {
500539
--j;
501540
}
502541
if (i != j) {
@@ -540,11 +579,13 @@ class intrusive_list {
540579
typedef intrusive_list_iterator<is_const> this_type;
541580
typedef T value_type;
542581
typedef std::ptrdiff_t difference_type;
543-
typedef typename std::conditional<is_const, const T&, T&>::type reference;
544-
typedef typename std::conditional<is_const, const T*, T*>::type pointer;
582+
typedef typename emulate_std::conditional<is_const, const T&, T&>::type
583+
reference;
584+
typedef typename emulate_std::conditional<is_const, const T*, T*>::type
585+
pointer;
545586
typedef std::bidirectional_iterator_tag iterator_category;
546-
typedef typename std::conditional<is_const, const intrusive_list_node,
547-
intrusive_list_node>::type node_type;
587+
typedef typename emulate_std::conditional<is_const,
588+
const intrusive_list_node, intrusive_list_node>::type node_type;
548589

549590
intrusive_list_iterator() : value_(nullptr) {}
550591

0 commit comments

Comments
 (0)