This differs from the previous patch in actually testing constexpr
:-\ and
in the addition of wrappers for __builtin_memmove and
__builtin_memcmp that
supply constexpr branches if C++20 and is_constant_evaluated().
+ void*
+ __memmove(_Tp* __dst, const _Tp* __src, ptrdiff_t __num)
+ {
+#if __cplusplus > 201703L
+ if (is_constant_evaluated())
+ {
+ for(; __num > 0; --__num)
+ {
+ *__dst = *__src;
+ ++__src;
+ ++__dst;
+ }
+ return __dst;
+ }
+ else if (__num)
+#endif
+ return __builtin_memmove(__dst, __src, sizeof(_Tp) *
abs(__num));
+ return __dst;
..
const ptrdiff_t _Num = __last - __first;
if (_Num)
- __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
+ __memmove(__result, __first, _Num);
..
const ptrdiff_t _Num = __last - __first;
if (_Num)
- __builtin_memmove(__result - _Num, __first, sizeof(_Tp)
* _Num);
+ __memmove(__result - _Num, __first, _Num);
Why the abs in there, that is something that wasn't previously
there and
if the compiler doesn't figure out that __last >= __first, it would
mean
larger emitted code for the non-constexpr case. As memmove
argument is
size_t, wouldn't it be better to make __num just size_t and remove
this abs?
Also, wouldn't it be better to have on the other side the __num == 0
handling inside of __memmove, you already have it there for C++2a,
but not
for older. You could then drop the if (_Num) guards around __memmove.