diff --git a/src/c_wrapper/clobj.h b/src/c_wrapper/clobj.h index fed644e5eb477848a29e01f8512fdaf91c8e6e25..660dd3ba1c7328914e06ec286b97f140f37b231b 100644 --- a/src/c_wrapper/clobj.h +++ b/src/c_wrapper/clobj.h @@ -53,10 +53,8 @@ print_clobj(std::ostream &stm, const CLObj *obj) } template<typename CLObj> -class CLArg<CLObj, - typename std::enable_if< - std::is_base_of<clobj<typename CLObj::cl_type>, - CLObj>::value>::type> { +class CLArg<CLObj, enable_if_t<std::is_base_of<clobj<typename CLObj::cl_type>, + CLObj>::value> > { private: CLObj &m_obj; public: @@ -76,10 +74,8 @@ public: }; template<typename CLObj> -class CLArg<CLObj*, - typename std::enable_if< - std::is_base_of<clobj<typename CLObj::cl_type>, - CLObj>::value>::type> { +class CLArg<CLObj*, enable_if_t<std::is_base_of<clobj<typename CLObj::cl_type>, + CLObj>::value> > { private: CLObj *m_obj; public: diff --git a/src/c_wrapper/error.h b/src/c_wrapper/error.h index 1bf4ab9fdad5be31028eb20d91fd2f311fbe6f6f..f77592a4c5bc6de204c529879dce4c0ec1c5d7be 100644 --- a/src/c_wrapper/error.h +++ b/src/c_wrapper/error.h @@ -106,8 +106,7 @@ struct __CLPrintOut { }; template<typename T> -struct __CLPrintOut<T, typename std::enable_if< - std::remove_reference<T>::type::is_out>::type> { +struct __CLPrintOut<T, enable_if_t<rm_ref_t<T>::is_out> > { static inline void call(T v, std::ostream &stm) { @@ -195,11 +194,10 @@ public: }; template<typename... Types> -static PYOPENCL_INLINE CLArgPack<typename std::remove_reference<Types>::type...> +static PYOPENCL_INLINE CLArgPack<rm_ref_t<Types>...> make_clargpack(Types&&... args) { - return CLArgPack<typename std::remove_reference<Types>::type...>( - std::forward<Types>(args)...); + return CLArgPack<rm_ref_t<Types>...>(std::forward<Types>(args)...); } template<typename... ArgTypes2, typename... ArgTypes> diff --git a/src/c_wrapper/function.h b/src/c_wrapper/function.h index 495483c85d5541d38f08d8a2bc5c04666ad13845..4277f730f25194433b398f94c9133e563f7ab868 100644 --- a/src/c_wrapper/function.h +++ b/src/c_wrapper/function.h @@ -12,6 +12,11 @@ namespace pyopencl { +template<typename T> +using rm_ref_t = typename std::remove_reference<T>::type; +template<bool B, class T = void> +using enable_if_t = typename std::enable_if<B, T>::type; + template<int...> struct seq { }; @@ -44,11 +49,8 @@ call_tuple(Function &&func, T &&args) typename gens<std::tuple_size<T>::value>::type(), args); } -template<typename T> -using _ArgType = typename std::remove_reference<T>::type; - template<template<typename...> class Convert, typename... Types> -using _ArgPackBase = std::tuple<Convert<_ArgType<Types> >...>; +using _ArgPackBase = std::tuple<Convert<rm_ref_t<Types> >...>; template<template<typename...> class Convert, typename... Types> class ArgPack : public _ArgPackBase<Convert, Types...> { @@ -69,7 +71,7 @@ private: } template<typename T> - using ArgConvert = Convert<_ArgType<T> >; + using ArgConvert = Convert<rm_ref_t<T> >; template<template<typename...> class Getter, int... S> PYOPENCL_INLINE auto __get(seq<S...>) @@ -84,7 +86,7 @@ private: public: template<typename... Types2> ArgPack(Types2&&... arg_orig) - : tuple_base(ArgConvert<_ArgType<Types> >(arg_orig)...) + : tuple_base(ArgConvert<rm_ref_t<Types> >(arg_orig)...) { } ArgPack(ArgPack<Convert, Types...> &&other) @@ -109,11 +111,10 @@ public: }; template<template<typename...> class Convert, typename... Types> -static PYOPENCL_INLINE ArgPack<Convert, _ArgType<Types>...> +static PYOPENCL_INLINE ArgPack<Convert, rm_ref_t<Types>...> make_argpack(Types&&... args) { - return ArgPack<Convert, _ArgType<Types>...>( - std::forward<Types>(args)...); + return ArgPack<Convert, rm_ref_t<Types>...>(std::forward<Types>(args)...); } } diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h index bd39f4df4d5495b50f33a3d6e15664b7a6aa677f..85810eddfd4bc9c0fc98af7c1c9753d47201cdb2 100644 --- a/src/c_wrapper/utils.h +++ b/src/c_wrapper/utils.h @@ -197,11 +197,21 @@ public: } }; +template<ArgType AT, typename T, class = void> +struct _ToArgBuffer { + static PYOPENCL_INLINE ArgBuffer<rm_ref_t<T>, AT> + convert(T &buf) + { + return ArgBuffer<rm_ref_t<T>, AT>(&buf, 1); + } +}; + template<ArgType AT=ArgType::None, typename T> -static PYOPENCL_INLINE ArgBuffer<T, AT> -arg_buf(T &buf) +static PYOPENCL_INLINE auto +arg_buf(T &&buf) + -> decltype(_ToArgBuffer<AT, T>::convert(std::forward<T>(buf))) { - return ArgBuffer<T, AT>(&buf, 1); + return _ToArgBuffer<AT, T>::convert(std::forward<T>(buf)); } template<ArgType AT=ArgType::None, typename T> @@ -222,8 +232,8 @@ template<typename Buff, class = void> struct _ArgBufferConverter; template<typename Buff> -struct _ArgBufferConverter<Buff, typename std::enable_if< - Buff::arg_type == ArgType::None>::type> { +struct _ArgBufferConverter<Buff, + enable_if_t<Buff::arg_type == ArgType::None> > { static PYOPENCL_INLINE typename Buff::type* convert(Buff &buff) { @@ -232,8 +242,8 @@ struct _ArgBufferConverter<Buff, typename std::enable_if< }; template<typename Buff> -struct _ArgBufferConverter<Buff, typename std::enable_if< - Buff::arg_type == ArgType::SizeOf>::type> { +struct _ArgBufferConverter<Buff, + enable_if_t<Buff::arg_type == ArgType::SizeOf> > { static PYOPENCL_INLINE auto convert(Buff &buff) -> decltype(std::make_tuple(sizeof(typename Buff::type) * buff.len(), @@ -245,8 +255,8 @@ struct _ArgBufferConverter<Buff, typename std::enable_if< }; template<typename Buff> -struct _ArgBufferConverter<Buff, typename std::enable_if< - Buff::arg_type == ArgType::Length>::type> { +struct _ArgBufferConverter<Buff, + enable_if_t<Buff::arg_type == ArgType::Length> > { static PYOPENCL_INLINE auto convert(Buff &buff) -> decltype(std::make_tuple(buff.len(), buff.get())) @@ -256,15 +266,13 @@ struct _ArgBufferConverter<Buff, typename std::enable_if< }; template<typename Buff> -class CLArg<Buff, typename std::enable_if<std::is_base_of< - ArgBuffer<typename Buff::type, +class CLArg<Buff, enable_if_t<std::is_base_of<ArgBuffer<typename Buff::type, Buff::arg_type>, - Buff>::value>::type> { + Buff>::value> > { private: Buff &m_buff; public: - constexpr static bool is_out = !(std::is_const<Buff>::value || - std::is_const<typename Buff::type>::value); + constexpr static bool is_out = !std::is_const<typename Buff::type>::value; CLArg(Buff &buff) noexcept : m_buff(buff) {} @@ -306,8 +314,7 @@ struct OutArg { }; template<typename T> -class CLArg<T, typename std::enable_if< - std::is_base_of<OutArg, T>::value>::type> { +class CLArg<T, enable_if_t<std::is_base_of<OutArg, T>::value> > { private: bool m_converted; bool m_need_cleanup; @@ -412,35 +419,36 @@ public: } }; +template<typename T, class = void> +struct is_pyopencl_buf { + constexpr static bool value = false; +}; + +template<typename T> +struct is_pyopencl_buf< + T, enable_if_t<std::is_base_of<pyopencl_buf<typename T::element_type>, + T>::value> > { + constexpr static bool value = true; +}; + template<typename Buff> -class CLArg<Buff, typename std::enable_if< - std::is_base_of< - pyopencl_buf<typename Buff::element_type>, - Buff>::value>::type> { -private: - Buff &m_buff; +using __pyopencl_buf_arg_type = + rm_ref_t<decltype(std::declval<Buff>().to_arg())>; + +template<typename Buff> +class CLArg<Buff, enable_if_t<is_pyopencl_buf<Buff>::value> > + : public CLArg<__pyopencl_buf_arg_type<Buff> > { + typedef __pyopencl_buf_arg_type<Buff> BufType; + BufType m_buff; public: - constexpr static bool is_out = - !(std::is_const<Buff>::value || - std::is_const<typename Buff::element_type>::value); + PYOPENCL_INLINE CLArg(Buff &buff) noexcept - : m_buff(buff) + : CLArg<BufType>(m_buff), m_buff(buff.to_arg()) {} + PYOPENCL_INLINE CLArg(CLArg<Buff> &&other) noexcept - : m_buff(other.m_buff) + : CLArg<BufType>(m_buff), m_buff(std::move(other.m_buff)) {} - PYOPENCL_INLINE auto - convert() const noexcept - -> decltype(std::make_tuple(m_buff.len(), m_buff.get())) - { - return std::make_tuple(m_buff.len(), m_buff.get()); - } - PYOPENCL_INLINE void - print(std::ostream &stm, bool out=false) - { - print_buf(stm, m_buff.get(), m_buff.len(), ArgType::Length, - out || !is_out, out); - } }; template<typename T>