blob: 0e8cae55aeebafd9ef54ec238b9f42380530c7e8 [file] [log] [blame]
/*
* Copyright (c) 2022 NVIDIA Corporation
*
* Licensed under the Apache License Version 2.0 with LLVM Exceptions
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://llvm.org/LICENSE.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "__config.hpp"
namespace stdexec
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// A very simple std::declval replacement that doesn't handle void
template <class _Tp>
_Tp&& __declval() noexcept;
//////////////////////////////////////////////////////////////////////////////////////////////////
// __decay_t: An efficient implementation for std::decay
#if STDEXEC_HAS_BUILTIN(__decay)
template <class _Ty>
using __decay_t = __decay(_Ty);
#elif STDEXEC_NVHPC()
template <class _Ty>
using __decay_t = std::decay_t<_Ty>;
#else
namespace __tt
{
struct __decay_object
{
template <class _Ty>
static _Ty __g(const _Ty&);
template <class _Ty>
using __f = decltype(__g(__declval<_Ty>()));
};
struct __decay_default
{
template <class _Ty>
static _Ty __g(_Ty);
template <class _Ty>
using __f = decltype(__g(__declval<_Ty>()));
};
struct __decay_abominable
{
template <class _Ty>
using __f = _Ty;
};
struct __decay_void
{
template <class _Ty>
using __f = void;
};
template <class _Ty>
extern __decay_object __mdecay;
template <class _Ty, class... Us>
extern __decay_default __mdecay<_Ty(Us...)>;
template <class _Ty, class... Us>
extern __decay_default __mdecay<_Ty(Us...) noexcept>;
template <class _Ty, class... Us>
extern __decay_default __mdecay<_Ty (&)(Us...)>;
template <class _Ty, class... Us>
extern __decay_default __mdecay<_Ty (&)(Us...) noexcept>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const noexcept>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const&>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const & noexcept>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const&&>;
template <class _Ty, class... Us>
extern __decay_abominable __mdecay<_Ty(Us...) const && noexcept>;
template <class _Ty>
extern __decay_default __mdecay<_Ty[]>;
template <class _Ty, std::size_t N>
extern __decay_default __mdecay<_Ty[N]>;
template <class _Ty, std::size_t N>
extern __decay_default __mdecay<_Ty (&)[N]>;
template <>
inline __decay_void __mdecay<void>;
template <>
inline __decay_void __mdecay<const void>;
} // namespace __tt
template <class _Ty>
using __decay_t = typename decltype(__tt::__mdecay<_Ty>)::template __f<_Ty>;
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////
// __copy_cvref_t: For copying cvref from one type to another
struct __cp
{
template <class _Tp>
using __f = _Tp;
};
struct __cpc
{
template <class _Tp>
using __f = const _Tp;
};
struct __cplr
{
template <class _Tp>
using __f = _Tp&;
};
struct __cprr
{
template <class _Tp>
using __f = _Tp&&;
};
struct __cpclr
{
template <class _Tp>
using __f = const _Tp&;
};
struct __cpcrr
{
template <class _Tp>
using __f = const _Tp&&;
};
template <class>
extern __cp __cpcvr;
template <class _Tp>
extern __cpc __cpcvr<const _Tp>;
template <class _Tp>
extern __cplr __cpcvr<_Tp&>;
template <class _Tp>
extern __cprr __cpcvr<_Tp&&>;
template <class _Tp>
extern __cpclr __cpcvr<const _Tp&>;
template <class _Tp>
extern __cpcrr __cpcvr<const _Tp&&>;
template <class _Tp>
using __copy_cvref_fn = decltype(__cpcvr<_Tp>);
template <class _From, class _To>
using __copy_cvref_t = typename __copy_cvref_fn<_From>::template __f<_To>;
#if !STDEXEC_HAS_BUILTIN(__is_const)
template <class>
inline constexpr bool __is_const = false;
template <class _Up>
inline constexpr bool __is_const<const _Up> = true;
#endif
namespace __tt
{
template <class _Ty>
_Ty __remove_rvalue_reference_fn(_Ty&&);
}
template <class _Ty>
using __remove_rvalue_reference_t =
decltype(__tt::__remove_rvalue_reference_fn(__declval<_Ty>()));
} // namespace stdexec