mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
105 lines
3.1 KiB
C++
105 lines
3.1 KiB
C++
/***************************************************************************
|
|
* Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
|
|
* Copyright (c) QuantStack *
|
|
* *
|
|
* Distributed under the terms of the BSD 3-Clause License. *
|
|
* *
|
|
* The full license is in the file LICENSE, distributed with this software. *
|
|
****************************************************************************/
|
|
|
|
#ifndef XTENSOR_VECTORIZE_HPP
|
|
#define XTENSOR_VECTORIZE_HPP
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
#include "xfunction.hpp"
|
|
#include "xutils.hpp"
|
|
|
|
namespace xt
|
|
{
|
|
|
|
/***************
|
|
* xvectorizer *
|
|
***************/
|
|
|
|
template <class F, class R>
|
|
class xvectorizer
|
|
{
|
|
public:
|
|
|
|
template <class... E>
|
|
using xfunction_type = xfunction<F, xclosure_t<E>...>;
|
|
|
|
template <class Func, class = std::enable_if_t<!std::is_same<std::decay_t<Func>, xvectorizer>::value>>
|
|
xvectorizer(Func&& f);
|
|
|
|
template <class... E>
|
|
xfunction_type<E...> operator()(E&&... e) const;
|
|
|
|
private:
|
|
|
|
typename std::remove_reference<F>::type m_f;
|
|
};
|
|
|
|
namespace detail
|
|
{
|
|
template <class F>
|
|
using get_function_type = remove_class_t<decltype(&std::remove_reference_t<F>::operator())>;
|
|
}
|
|
|
|
template <class R, class... Args>
|
|
xvectorizer<R (*)(Args...), R> vectorize(R (*f)(Args...));
|
|
|
|
template <class F, class R, class... Args>
|
|
xvectorizer<F, R> vectorize(F&& f, R (*)(Args...));
|
|
|
|
// Workaround for Visual Studio 15.7.1.
|
|
// Error C2668 (ambiguous call to overloaded function) mistaking a declarations
|
|
// for the definition of another overload.
|
|
#ifndef _MSC_VER
|
|
template <class F>
|
|
auto vectorize(F&& f)
|
|
-> decltype(vectorize(std::forward<F>(f), std::declval<detail::get_function_type<F>*>()));
|
|
#endif
|
|
|
|
/******************************
|
|
* xvectorizer implementation *
|
|
******************************/
|
|
|
|
template <class F, class R>
|
|
template <class Func, class>
|
|
inline xvectorizer<F, R>::xvectorizer(Func&& f)
|
|
: m_f(std::forward<Func>(f))
|
|
{
|
|
}
|
|
|
|
template <class F, class R>
|
|
template <class... E>
|
|
inline auto xvectorizer<F, R>::operator()(E&&... e) const -> xfunction_type<E...>
|
|
{
|
|
return xfunction_type<E...>(m_f, std::forward<E>(e)...);
|
|
}
|
|
|
|
template <class R, class... Args>
|
|
inline xvectorizer<R (*)(Args...), R> vectorize(R (*f)(Args...))
|
|
{
|
|
return xvectorizer<R (*)(Args...), R>(f);
|
|
}
|
|
|
|
template <class F, class R, class... Args>
|
|
inline xvectorizer<F, R> vectorize(F&& f, R (*)(Args...))
|
|
{
|
|
return xvectorizer<F, R>(std::forward<F>(f));
|
|
}
|
|
|
|
template <class F>
|
|
inline auto vectorize(F&& f)
|
|
-> decltype(vectorize(std::forward<F>(f), std::declval<detail::get_function_type<F>*>()))
|
|
{
|
|
return vectorize(std::forward<F>(f), static_cast<detail::get_function_type<F>*>(nullptr));
|
|
}
|
|
}
|
|
|
|
#endif
|