#ifndef HALIDE_PARAM_H
#define HALIDE_PARAM_H
#include <type_traits>
#include "Argument.h"
#include "IR.h"
namespace Halide {
template<typename T>
class Param {
Internal::Parameter param;
void check_name() const {
user_assert(param.name() != "__user_context") << "Param<void*>(\"__user_context\") "
<< "is no longer used to control whether Halide functions take explicit "
<< "user_context arguments. Use set_custom_user_context() when jitting, "
<< "or add Target::UserContext to the Target feature set when compiling ahead of time.";
}
public:
Param() :
param(type_of<T>(), false, 0, Internal::make_entity_name(this, "Halide::Param<?", 'p')) {}
explicit Param(const std::string &n) :
param(type_of<T>(), false, 0, n, true) {
check_name();
}
explicit Param(const char *n) :
param(type_of<T>(), false, 0, n, true) {
check_name();
}
template <typename T2 = T, typename std::enable_if<!std::is_pointer<T2>::value>::type * = nullptr>
explicit Param(T val) :
param(type_of<T>(), false, 0, Internal::make_entity_name(this, "Halide::Param<?", 'p')) {
set(val);
}
Param(const std::string &n, T val) :
param(type_of<T>(), false, 0, n, true) {
check_name();
set(val);
}
Param(T val, Expr min, Expr max) :
param(type_of<T>(), false, 0, Internal::make_entity_name(this, "Halide::Param<?", 'p')) {
set_range(min, max);
set(val);
}
Param(const std::string &n, T val, Expr min, Expr max) :
param(type_of<T>(), false, 0, n, true) {
check_name();
set_range(min, max);
set(val);
}
const std::string &name() const {
return param.name();
}
bool is_explicit_name() const {
return param.is_explicit_name();
}
NO_INLINE T get() const {
return param.get_scalar<T>();
}
NO_INLINE void set(T val) {
param.set_scalar<T>(val);
}
NO_INLINE T *get_address() const {
return (T *)(param.get_scalar_address());
}
Type type() const {
return type_of<T>();
}
void set_range(Expr min, Expr max) {
set_min_value(min);
set_max_value(max);
}
void set_min_value(Expr min) {
if (min.defined() && min.type() != type_of<T>()) {
min = Internal::Cast::make(type_of<T>(), min);
}
param.set_min_value(min);
}
void set_max_value(Expr max) {
if (max.defined() && max.type() != type_of<T>()) {
max = Internal::Cast::make(type_of<T>(), max);
}
param.set_max_value(max);
}
Expr get_min_value() const {
return param.get_min_value();
}
Expr get_max_value() const {
return param.get_max_value();
}
operator Expr() const {
return Internal::Variable::make(type_of<T>(), name(), param);
}
operator ExternFuncArgument() const {
return Expr(*this);
}
operator Argument() const {
return Argument(name(), Argument::InputScalar, type(), 0,
param.get_scalar_expr(), param.get_min_value(), param.get_max_value());
}
};
inline Expr user_context_value() {
return Internal::Variable::make(Handle(), "__user_context",
Internal::Parameter(Handle(), false, 0, "__user_context", true));
}
}
#endif