9#ifndef FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_
10#define FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_
12#include "flang/Common/api-attrs.h"
13#include "flang/Runtime/c-or-cpp.h"
21#if !defined(STD_FILL_N_UNSUPPORTED) && \
22 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
23#define STD_FILL_N_UNSUPPORTED 1
26#if !defined(STD_MEMMOVE_UNSUPPORTED) && \
27 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
28#define STD_MEMMOVE_UNSUPPORTED 1
31#if !defined(STD_STRLEN_UNSUPPORTED) && \
32 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
33#define STD_STRLEN_UNSUPPORTED 1
36#if !defined(STD_MEMCMP_UNSUPPORTED) && \
37 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
38#define STD_MEMCMP_UNSUPPORTED 1
41#if !defined(STD_REALLOC_UNSUPPORTED) && \
42 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
43#define STD_REALLOC_UNSUPPORTED 1
46#if !defined(STD_MEMCHR_UNSUPPORTED) && \
47 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
48#define STD_MEMCHR_UNSUPPORTED 1
51#if !defined(STD_STRCPY_UNSUPPORTED) && \
52 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
53#define STD_STRCPY_UNSUPPORTED 1
56#if !defined(STD_STRCMP_UNSUPPORTED) && \
57 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
58#define STD_STRCMP_UNSUPPORTED 1
61#if !defined(STD_TOUPPER_UNSUPPORTED) && \
62 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
63#define STD_TOUPPER_UNSUPPORTED 1
66namespace Fortran::runtime {
68#if STD_FILL_N_UNSUPPORTED
71template <
typename A,
typename B>
72static inline RT_API_ATTRS std::enable_if_t<std::is_convertible_v<B, A>,
void>
73fill_n(A *start, std::size_t count,
const B &value) {
74 for (std::size_t j{0}; j < count; ++j) {
82#if STD_MEMMOVE_UNSUPPORTED
85static inline RT_API_ATTRS
void *memmove(
86 void *dest,
const void *src, std::size_t count) {
87 char *to{
reinterpret_cast<char *
>(dest)};
88 const char *from{
reinterpret_cast<const char *
>(src)};
93 if (to + count <= from || from + count <= to) {
94 std::memcpy(dest, src, count);
95 }
else if (to < from) {
112using MemmoveFct =
void *(*)(
void *,
const void *, std::size_t);
114#ifdef RT_DEVICE_COMPILATION
115static RT_API_ATTRS
void *MemmoveWrapper(
116 void *dest,
const void *src, std::size_t count) {
117 return Fortran::runtime::memmove(dest, src, count);
121#if STD_STRLEN_UNSUPPORTED
124static inline RT_API_ATTRS std::size_t strlen(
const char *str) {
129 const char *end = str;
130 for (; *end !=
'\0'; ++end)
138#if STD_MEMCMP_UNSUPPORTED
141static inline RT_API_ATTRS
int memcmp(
142 const void *RESTRICT lhs,
const void *RESTRICT rhs, std::size_t count) {
143 auto m1{
reinterpret_cast<const unsigned char *
>(lhs)};
144 auto m2{
reinterpret_cast<const unsigned char *
>(rhs)};
145 for (; count--; ++m1, ++m2) {
146 int diff = *m1 - *m2;
157#if STD_REALLOC_UNSUPPORTED
158static inline RT_API_ATTRS
void *realloc(
void *ptr, std::size_t newByteSize) {
168#if STD_MEMCHR_UNSUPPORTED
171static inline RT_API_ATTRS
const void *memchr(
172 const void *ptr,
int ch, std::size_t count) {
173 auto buf{
reinterpret_cast<const unsigned char *
>(ptr)};
174 auto c{
static_cast<unsigned char>(ch)};
175 for (; count--; ++buf) {
186#if STD_STRCPY_UNSUPPORTED
189static inline RT_API_ATTRS
char *strcpy(
char *dest,
const char *src) {
193 }
while (*src++ !=
'\0');
200#if STD_STRCMP_UNSUPPORTED
203static inline RT_API_ATTRS
int strcmp(
const char *lhs,
const char *rhs) {
204 while (*lhs !=
'\0' && *lhs == *rhs) {
208 return static_cast<unsigned char>(*lhs) -
static_cast<unsigned char>(*rhs);
214#if STD_TOUPPER_UNSUPPORTED
217static inline RT_API_ATTRS
int toupper(
int ch) {
218 if (ch >=
'a' && ch <=
'z') {
219 return ch -
'a' +
'A';