Skip to content

Commit 7307e6f

Browse files
committed
Fix constant evaluation due to non-constant pointer_traits::pointer_to for gcc
1 parent 3f73d1a commit 7307e6f

File tree

1 file changed

+64
-11
lines changed

1 file changed

+64
-11
lines changed

libcxx/include/forward_list

+64-11
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ template <class T, class Allocator, class Predicate>
228228
# include <__type_traits/enable_if.h>
229229
# include <__type_traits/is_allocator.h>
230230
# include <__type_traits/is_const.h>
231+
# include <__type_traits/is_constant_evaluated.h>
231232
# include <__type_traits/is_nothrow_assignable.h>
232233
# include <__type_traits/is_nothrow_constructible.h>
233234
# include <__type_traits/is_pointer.h>
@@ -300,7 +301,16 @@ struct __forward_node_traits {
300301
return __p;
301302
}
302303
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI static __begin_node_pointer __as_iter_node(__node_pointer __p) {
303-
return __p ? pointer_traits<__begin_node_pointer>::pointer_to(*__p) : static_cast<__begin_node_pointer>(nullptr);
304+
if (__libcpp_is_constant_evaluated()) {
305+
if constexpr (std::is_pointer<__begin_node_pointer>::value) {
306+
return static_cast<__begin_node_pointer>(__p);
307+
} else {
308+
return __p ? __begin_node_pointer::pointer_to(*static_cast<__begin_node*>(std::addressof(*__p)))
309+
: static_cast<__begin_node_pointer>(nullptr);
310+
}
311+
} else {
312+
return static_cast<__begin_node_pointer>(__p);
313+
}
304314
}
305315
};
306316

@@ -315,8 +325,16 @@ struct __forward_begin_node {
315325
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __forward_begin_node(pointer __n) : __next_(__n) {}
316326

317327
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __next_as_begin() const {
318-
return __next_ ? pointer_traits<__begin_node_pointer>::pointer_to(*__next_)
319-
: static_cast<__begin_node_pointer>(nullptr);
328+
if (__libcpp_is_constant_evaluated()) {
329+
if constexpr (std::is_pointer<__begin_node_pointer>::value) {
330+
return static_cast<__begin_node_pointer>(__next_);
331+
} else {
332+
return __next_ ? __begin_node_pointer::pointer_to(*static_cast<__forward_begin_node*>(std::addressof(*__next_)))
333+
: static_cast<__begin_node_pointer>(nullptr);
334+
}
335+
} else {
336+
return static_cast<__begin_node_pointer>(__next_);
337+
}
320338
}
321339
};
322340

@@ -363,6 +381,7 @@ template <class _NodePtr>
363381
class _LIBCPP_TEMPLATE_VIS __forward_list_iterator {
364382
typedef __forward_node_traits<_NodePtr> __traits;
365383
typedef typename __traits::__node_type __node_type;
384+
typedef typename __traits::__begin_node __begin_node_type;
366385
typedef typename __traits::__node_pointer __node_pointer;
367386
typedef typename __traits::__begin_node_pointer __begin_node_pointer;
368387
typedef typename __traits::__void_pointer __void_pointer;
@@ -371,9 +390,17 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_iterator {
371390

372391
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const { return __ptr_; }
373392
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
374-
return __ptr_ ? pointer_traits<__node_pointer>::pointer_to(
375-
const_cast<__node_type&>(static_cast<const __node_type&>(*__ptr_)))
376-
: static_cast<__node_pointer>(nullptr);
393+
if (__libcpp_is_constant_evaluated()) {
394+
if constexpr (std::is_pointer<__node_pointer>::value) {
395+
return static_cast<__node_pointer>(__ptr_);
396+
} else {
397+
return __ptr_ ? __node_pointer::pointer_to(
398+
*static_cast<__node_type*>(const_cast<__begin_node_type*>(std::addressof(*__ptr_))))
399+
: static_cast<__node_pointer>(nullptr);
400+
}
401+
} else {
402+
return static_cast<__node_pointer>(__ptr_);
403+
}
377404
}
378405

379406
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __forward_list_iterator(nullptr_t) _NOEXCEPT
@@ -434,6 +461,7 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator {
434461

435462
typedef __forward_node_traits<_NodePtr> __traits;
436463
typedef typename __traits::__node_type __node_type;
464+
typedef typename __traits::__begin_node __begin_node_type;
437465
typedef typename __traits::__node_pointer __node_pointer;
438466
typedef typename __traits::__begin_node_pointer __begin_node_pointer;
439467
typedef typename __traits::__void_pointer __void_pointer;
@@ -442,9 +470,17 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator {
442470

443471
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const { return __ptr_; }
444472
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const {
445-
return __ptr_ ? pointer_traits<__node_pointer>::pointer_to(
446-
const_cast<__node_type&>(static_cast<const __node_type&>(*__ptr_)))
447-
: static_cast<__node_pointer>(nullptr);
473+
if (__libcpp_is_constant_evaluated()) {
474+
if constexpr (std::is_pointer<__node_pointer>::value) {
475+
return static_cast<__node_pointer>(__ptr_);
476+
} else {
477+
return __ptr_ ? __node_pointer::pointer_to(
478+
*static_cast<__node_type*>(const_cast<__begin_node_type*>(std::addressof(*__ptr_))))
479+
: static_cast<__node_pointer>(nullptr);
480+
}
481+
} else {
482+
return static_cast<__node_pointer>(__ptr_);
483+
}
448484
}
449485

450486
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT
@@ -518,10 +554,27 @@ protected:
518554
_LIBCPP_COMPRESSED_PAIR(__begin_node, __before_begin_, __node_allocator, __alloc_);
519555

520556
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() _NOEXCEPT {
521-
return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_);
557+
if (__libcpp_is_constant_evaluated()) {
558+
if constexpr (std::is_pointer<__begin_node_pointer>::value) {
559+
return std::addressof(__before_begin_);
560+
} else {
561+
return __begin_node_pointer::pointer_to(*std::addressof(__before_begin_));
562+
}
563+
} else {
564+
return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_);
565+
}
522566
}
567+
523568
_LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __before_begin() const _NOEXCEPT {
524-
return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_));
569+
if (__libcpp_is_constant_evaluated()) {
570+
if constexpr (std::is_pointer<__begin_node_pointer>::value) {
571+
return const_cast<__begin_node*>(std::addressof(__before_begin_));
572+
} else {
573+
return __begin_node_pointer::pointer_to(*const_cast<__begin_node*>(std::addressof(__before_begin_)));
574+
}
575+
} else {
576+
return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_));
577+
}
525578
}
526579

527580
typedef __forward_list_iterator<__node_pointer> iterator;

0 commit comments

Comments
 (0)