cuda-kat
CUDA kernel author's tools
reference_wrapper.hpp
Go to the documentation of this file.
1 
9 //
10 // Original code Copyright (c) Electronic Arts Inc. All rights reserved
11 // Modifications Copyright (c) 2020 Eyal Rozenberg.
12 //
13 // Redistribution and use in source and binary forms, with or without
14 // modification, are permitted provided that the following conditions are met:
15 //
16 // 1. Redistributions of source code must retain the above copyright notice, this
17 // list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright notice,
20 // this list of conditions and the following disclaimer in the documentation
21 // and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the copyright holder nor the names of its
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
31 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Note: Retrieved from https://github.com/electronicarts/EASTL/ , master branch,
39 // on 2020-03-11.
40 
41 
42 #ifndef CUDA_KAT_REFERENCE_WRAPPER_HPP_
43 #define CUDA_KAT_REFERENCE_WRAPPER_HPP_
44 
45 #include <kat/common.hpp>
46 #include <kat/utility.hpp>
47 #include <type_traits>
48 
49 namespace kat {
50 
52 template <typename T>
54 {
55 public:
56  typedef T type;
57 
58  KAT_HD reference_wrapper(T&) noexcept;
59  KAT_HD reference_wrapper(T&&) = delete;
60  KAT_HD reference_wrapper(const reference_wrapper<T>& x) noexcept;
61 
62  KAT_HD reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept;
63 
64  KAT_HD operator T& () const noexcept;
65  KAT_HD T& get() const noexcept;
66 
67  template <typename... ArgTypes>
68  KAT_HD typename std::result_of<T&(ArgTypes&&...)>::type operator() (ArgTypes&&...) const;
69 
70 private:
71  T* val;
72 };
73 
74 template <typename T>
75 KAT_HD reference_wrapper<T>::reference_wrapper(T &v) noexcept
76 // Originally, EASTL has:
77 //
78 // : val(addressof(v))
79 //
80 // here. But we can't use std::addressof, since it is not accessible in device-side code;
81 // and we don't have the utility functions in <memory> implemented in device-and-host versions.
82 // So - we'll just inline an implementation of std::addressof() here instead
83  : val(
84  reinterpret_cast<T*>(
85  &const_cast<char&>(
86  reinterpret_cast<const volatile char&>(v)
87  )
88  )
89  )
90 {}
91 
92 template <typename T>
94  : val(other.val)
95 {}
96 
97 template <typename T>
99 {
100  val = other.val;
101  return *this;
102 }
103 
104 template <typename T>
105 KAT_HD reference_wrapper<T>::operator T&() const noexcept
106 {
107  return *val;
108 }
109 
110 template <typename T>
111 KAT_HD T& reference_wrapper<T>::get() const noexcept
112 {
113  return *val;
114 }
115 
116 template <typename T>
117 template <typename... ArgTypes>
118 KAT_HD typename std::result_of<T&(ArgTypes&&...)>::type reference_wrapper<T>::operator() (ArgTypes&&... args) const
119 {
120  // return std::invoke(*val, std::forward<ArgTypes>(args)...);
121  return *val(std::forward<ArgTypes>(args)...);
122 }
123 
124 // reference_wrapper-specific utilties
125 template <typename T>
126 KAT_HD reference_wrapper<T> ref(T& t) noexcept
127 {
128  return kat::reference_wrapper<T>(t);
129 }
130 
131 template <typename T>
132 KAT_HD void ref(const T&&) = delete;
133 
134 template <typename T>
135 KAT_HD reference_wrapper<T> ref(reference_wrapper<T>t) noexcept
136 {
137  return kat::ref(t.get());
138 }
139 
140 template <typename T>
141 KAT_HD reference_wrapper<const T> cref(const T& t) noexcept
142 {
144 }
145 
146 template <typename T>
147 KAT_HD void cref(const T&&) = delete;
148 
149 template <typename T>
150 KAT_HD reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept
151 {
152  return kat::cref(t.get());
153 }
154 
155 
156 // reference_wrapper-specific type traits
157 template <typename T>
159  : public std::false_type {};
160 
161 template <typename T>
163  : public std::true_type {};
164 
165 template <typename T>
167  : public kat::is_reference_wrapper_helper<typename std::remove_cv<T>::type> {};
168 
169 
170 // Helper which adds a reference to a type when given a reference_wrapper of that type.
171 template <typename T>
173  { typedef T type; };
174 
175 template <typename T>
177  { typedef T& type; };
178 
179 template <typename T>
181  { typedef T& type; };
182 
183 /*
184 // reference_wrapper specializations of invoke
185 // These have to come after reference_wrapper is defined, but reference_wrapper needs to have a
186 // definition of invoke, so these specializations need to come after everything else has been defined.
187 template <typename R, typename C, typename T, typename... Args>
188 auto invoke_impl(R (C::*func)(Args...), T&& obj, Args&&... args) ->
189  typename std::enable_if<is_reference_wrapper<typename std::remove_reference<T>::type>::value,
190  decltype((obj.get().*func)(std::forward<Args>(args)...))>::type
191 {
192  return (obj.get().*func)(std::forward<Args>(args)...);
193 }
194 
195 template <typename M, typename C, typename T>
196 auto invoke_impl(M(C::*member), T&& obj) ->
197  typename enable_if<is_reference_wrapper<typename remove_reference<T>::type>::value,
198  decltype(obj.get().*member)>::type
199 {
200  return obj.get().*member;
201 }
202 */
203 
204 } // namespace kat
205 
206 #endif // CUDA_KAT_REFERENCE_WRAPPER_HPP_
reference_wrapper
Definition: reference_wrapper.hpp:53
Definition: common.hpp:16
Definition: reference_wrapper.hpp:166
Definition: reference_wrapper.hpp:172
Basic type and macro definitions used throughout the KAT library.
An adaptation for host-and-device use of some of the standard C++ library&#39;s <utility> code...
Definition: reference_wrapper.hpp:158