Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- include/flang/Common/reference-wrapper.h ----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// clang-format off
9//
10// Implementation of std::reference_wrapper borrowed from libcu++
11// https://github.com/NVIDIA/libcudacxx/blob/f7e6cd07ed5ba826aeac0b742feafddfedc1e400/include/cuda/std/detail/libcxx/include/__functional/reference_wrapper.h#L1
12// with modifications.
13//
14// The original source code is distributed under the Apache License v2.0
15// with LLVM Exceptions.
16//
17// TODO: using libcu++ is the best option for CUDA, but there is a couple
18// of issues:
19// * The include paths need to be set up such that all STD header files
20// are taken from libcu++.
21// * cuda:: namespace need to be forced for all std:: references.
22//
23// clang-format on
24
25#ifndef FORTRAN_COMMON_REFERENCE_WRAPPER_H
26#define FORTRAN_COMMON_REFERENCE_WRAPPER_H
27
28#include "flang/Common/api-attrs.h"
29#include <functional>
30#include <type_traits>
31
32#if !defined(STD_REFERENCE_WRAPPER_UNSUPPORTED) && \
33 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
34#define STD_REFERENCE_WRAPPER_UNSUPPORTED 1
35#endif
36
37namespace Fortran::common {
38
39template <class _Tp>
40using __remove_cvref_t = std::remove_cv_t<std::remove_reference_t<_Tp>>;
41template <class _Tp, class _Up>
42struct __is_same_uncvref
43 : std::is_same<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up>> {};
44
45#if STD_REFERENCE_WRAPPER_UNSUPPORTED
46template <class _Tp> class reference_wrapper {
47public:
48 // types
49 typedef _Tp type;
50
51private:
52 type *__f_;
53
54 static RT_API_ATTRS void __fun(_Tp &);
55 static void __fun(_Tp &&) = delete;
56
57public:
58 template <class _Up,
59 class =
60 std::enable_if_t<!__is_same_uncvref<_Up, reference_wrapper>::value,
61 decltype(__fun(std::declval<_Up>()))>>
62 constexpr RT_API_ATTRS reference_wrapper(_Up &&__u) {
63 type &__f = static_cast<_Up &&>(__u);
64 __f_ = std::addressof(__f);
65 }
66
67 // access
68 constexpr RT_API_ATTRS operator type &() const { return *__f_; }
69 constexpr RT_API_ATTRS type &get() const { return *__f_; }
70
71 // invoke
72 template <class... _ArgTypes>
73 constexpr RT_API_ATTRS typename std::invoke_result_t<type &, _ArgTypes...>
74 operator()(_ArgTypes &&...__args) const {
75 return std::invoke(get(), std::forward<_ArgTypes>(__args)...);
76 }
77};
78
79template <class _Tp> reference_wrapper(_Tp &) -> reference_wrapper<_Tp>;
80
81template <class _Tp>
82inline constexpr RT_API_ATTRS reference_wrapper<_Tp> ref(_Tp &__t) {
83 return reference_wrapper<_Tp>(__t);
84}
85
86template <class _Tp>
87inline constexpr RT_API_ATTRS reference_wrapper<_Tp> ref(
88 reference_wrapper<_Tp> __t) {
89 return __t;
90}
91
92template <class _Tp>
93inline constexpr RT_API_ATTRS reference_wrapper<const _Tp> cref(
94 const _Tp &__t) {
95 return reference_wrapper<const _Tp>(__t);
96}
97
98template <class _Tp>
99inline constexpr RT_API_ATTRS reference_wrapper<const _Tp> cref(
100 reference_wrapper<_Tp> __t) {
101 return __t;
102}
103
104template <class _Tp> void ref(const _Tp &&) = delete;
105template <class _Tp> void cref(const _Tp &&) = delete;
106#else // !STD_REFERENCE_WRAPPER_UNSUPPORTED
107using std::cref;
108using std::ref;
109using std::reference_wrapper;
110#endif // !STD_REFERENCE_WRAPPER_UNSUPPORTED
111
112} // namespace Fortran::common
113
114#endif // FORTRAN_COMMON_REFERENCE_WRAPPER_H
115

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of flang/include/flang/Common/reference-wrapper.h