79 lines
2.5 KiB
C++
79 lines
2.5 KiB
C++
|
// Copyright 2023 Matt Borland
|
|||
|
// Distributed under the Boost Software License, Version 1.0.
|
|||
|
// https://www.boost.org/LICENSE_1_0.txt
|
|||
|
|
|||
|
#ifndef BOOST_CHARCONV_DETAIL_MEMCPY_HPP
|
|||
|
#define BOOST_CHARCONV_DETAIL_MEMCPY_HPP
|
|||
|
|
|||
|
#include <boost/charconv/detail/config.hpp>
|
|||
|
#include <cstring>
|
|||
|
#include <cstdint>
|
|||
|
|
|||
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89689
|
|||
|
// GCC 10 added checks for length of memcpy which yields the following warning (converted to error with -Werror)
|
|||
|
// /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34:33: error:
|
|||
|
// ‘void* __builtin___memcpy_chk(void*, const void*, long unsigned int, long unsigned int)’ specified size between
|
|||
|
// 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=]
|
|||
|
//
|
|||
|
// memcpy is defined as taking a size_t for the count and the largest count this will recieve is the number of digits
|
|||
|
// in a 128-bit int (39) so we can safely ignore
|
|||
|
#if defined(__GNUC__) && __GNUC__ >= 10
|
|||
|
# pragma GCC diagnostic push
|
|||
|
# pragma GCC diagnostic ignored "-Wstringop-overflow"
|
|||
|
# define BOOST_CHARCONV_STRINGOP_OVERFLOW_DISABLED
|
|||
|
#endif
|
|||
|
|
|||
|
namespace boost { namespace charconv { namespace detail {
|
|||
|
|
|||
|
#if !defined(BOOST_CHARCONV_NO_CONSTEXPR_DETECTION) && defined(BOOST_CXX14_CONSTEXPR)
|
|||
|
|
|||
|
#define BOOST_CHARCONV_CONSTEXPR constexpr
|
|||
|
|
|||
|
constexpr char* memcpy(char* dest, const char* src, std::size_t count)
|
|||
|
{
|
|||
|
if (BOOST_CHARCONV_IS_CONSTANT_EVALUATED(count))
|
|||
|
{
|
|||
|
for (std::size_t i = 0; i < count; ++i)
|
|||
|
{
|
|||
|
*(dest + i) = *(src + i);
|
|||
|
}
|
|||
|
|
|||
|
return dest;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Workaround for GCC-11 because it does not honor GCC diagnostic ignored
|
|||
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
|
|||
|
// Hopefully the optimizer turns this into memcpy
|
|||
|
#if defined(__GNUC__) && __GNUC__ == 11
|
|||
|
for (std::size_t i = 0; i < count; ++i)
|
|||
|
{
|
|||
|
*(dest + i) = *(src + i);
|
|||
|
}
|
|||
|
|
|||
|
return dest;
|
|||
|
#else
|
|||
|
return static_cast<char*>(std::memcpy(dest, src, count));
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#else // Either not C++14 or no way of telling if we are in a constexpr context
|
|||
|
|
|||
|
#define BOOST_CHARCONV_CONSTEXPR inline
|
|||
|
|
|||
|
inline void* memcpy(void* dest, const void* src, std::size_t count)
|
|||
|
{
|
|||
|
return std::memcpy(dest, src, count);
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
}}} // Namespace boost::charconv::detail
|
|||
|
|
|||
|
#ifdef BOOST_CHARCONV_STRINGOP_OVERFLOW_DISABLED
|
|||
|
# pragma GCC diagnostic pop
|
|||
|
#endif
|
|||
|
|
|||
|
#endif // BOOST_CHARCONV_DETAIL_MEMCPY_HPP
|