Home | History | Annotate | Download | only in cuda_wrappers
      1 /*===---- complex - CUDA wrapper for <algorithm> ----------------------------===
      2  *
      3  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  * of this software and associated documentation files (the "Software"), to deal
      5  * in the Software without restriction, including without limitation the rights
      6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      7  * copies of the Software, and to permit persons to whom the Software is
      8  * furnished to do so, subject to the following conditions:
      9  *
     10  * The above copyright notice and this permission notice shall be included in
     11  * all copies or substantial portions of the Software.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     19  * THE SOFTWARE.
     20  *
     21  *===-----------------------------------------------------------------------===
     22  */
     23 
     24 #ifndef __CLANG_CUDA_WRAPPERS_ALGORITHM
     25 #define __CLANG_CUDA_WRAPPERS_ALGORITHM
     26 
     27 // This header defines __device__ overloads of std::min/max, but only if we're
     28 // <= C++11.  In C++14, these functions are constexpr, and so are implicitly
     29 // __host__ __device__.
     30 //
     31 // We don't support the initializer_list overloads because
     32 // initializer_list::begin() and end() are not __host__ __device__ functions.
     33 //
     34 // When compiling in C++14 mode, we could force std::min/max to have different
     35 // implementations for host and device, by declaring the device overloads
     36 // before the constexpr overloads appear.  We choose not to do this because
     37 
     38 //  a) why write our own implementation when we can use one from the standard
     39 //     library? and
     40 //  b) libstdc++ is evil and declares min/max inside a header that is included
     41 //     *before* we include <algorithm>.  So we'd have to unconditionally
     42 //     declare our __device__ overloads of min/max, but that would pollute
     43 //     things for people who choose not to include <algorithm>.
     44 
     45 #include_next <algorithm>
     46 
     47 #if __cplusplus <= 201103L
     48 
     49 // We need to define these overloads in exactly the namespace our standard
     50 // library uses (including the right inline namespace), otherwise they won't be
     51 // picked up by other functions in the standard library (e.g. functions in
     52 // <complex>).  Thus the ugliness below.
     53 #ifdef _LIBCPP_BEGIN_NAMESPACE_STD
     54 _LIBCPP_BEGIN_NAMESPACE_STD
     55 #else
     56 namespace std {
     57 #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
     58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     59 #endif
     60 #endif
     61 
     62 template <class __T, class __Cmp>
     63 inline __device__ const __T &
     64 max(const __T &__a, const __T &__b, __Cmp __cmp) {
     65   return __cmp(__a, __b) ? __b : __a;
     66 }
     67 
     68 template <class __T>
     69 inline __device__ const __T &
     70 max(const __T &__a, const __T &__b) {
     71   return __a < __b ? __b : __a;
     72 }
     73 
     74 template <class __T, class __Cmp>
     75 inline __device__ const __T &
     76 min(const __T &__a, const __T &__b, __Cmp __cmp) {
     77   return __cmp(__b, __a) ? __b : __a;
     78 }
     79 
     80 template <class __T>
     81 inline __device__ const __T &
     82 min(const __T &__a, const __T &__b) {
     83   return __a < __b ? __b : __a;
     84 }
     85 
     86 #ifdef _LIBCPP_END_NAMESPACE_STD
     87 _LIBCPP_END_NAMESPACE_STD
     88 #else
     89 #ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
     90 _GLIBCXX_END_NAMESPACE_VERSION
     91 #endif
     92 } // namespace std
     93 #endif
     94 
     95 #endif // __cplusplus <= 201103L
     96 #endif // __CLANG_CUDA_WRAPPERS_ALGORITHM
     97