#ifdef NDEBUG
#undef NDEBUG
#include <assert.h>
#define NDEBUG
#else
#include <assert.h>
#endif
#ifndef HALIDE_UTIL_H
#define HALIDE_UTIL_H
#include <cstdint>
#include <utility>
#include <vector>
#include <string>
#include <cstring>
#if defined(_WIN32) && defined(Halide_SHARED)
#ifdef Halide_EXPORTS
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
#else
#define EXPORT
#endif
#if defined(COMPILING_HALIDE) || defined(BUILDING_PYTHON)
#define NO_INLINE
#else
#ifdef _WIN32
#define NO_INLINE __declspec(noinline)
#else
#define NO_INLINE __attribute__((noinline))
#endif
#endif
#ifdef _MSC_VER
#pragma comment(linker, "/STACK:8388608,1048576")
#endif
namespace Halide {
namespace Internal {
template<typename DstType, typename SrcType>
DstType reinterpret_bits(const SrcType &src) {
static_assert(sizeof(SrcType) == sizeof(DstType), "Types must be same size");
DstType dst;
memcpy(&dst, &src, sizeof(SrcType));
return dst;
}
EXPORT std::string make_entity_name(void *stack_ptr, const std::string &type, char prefix);
EXPORT std::string get_env_variable(char const *env_var_name);
EXPORT std::string running_program_name();
EXPORT std::string unique_name(char prefix);
EXPORT std::string unique_name(const std::string &prefix);
EXPORT bool starts_with(const std::string &str, const std::string &prefix);
EXPORT bool ends_with(const std::string &str, const std::string &suffix);
EXPORT std::string replace_all(const std::string &str, const std::string &find, const std::string &replace);
EXPORT std::vector<std::string> split_string(const std::string &source, const std::string &delim);
template<typename T, typename Fn>
T fold_left(const std::vector<T> &vec, Fn f) {
T result;
if (vec.empty()) {
return result;
}
result = vec[0];
for (size_t i = 1; i < vec.size(); i++) {
result = f(result, vec[i]);
}
return result;
}
template<typename T, typename Fn>
T fold_right(const std::vector<T> &vec, Fn f) {
T result;
if (vec.empty()) {
return result;
}
result = vec.back();
for (size_t i = vec.size()-1; i > 0; i--) {
result = f(vec[i-1], result);
}
return result;
}
template <typename T1, typename T2, typename T3, typename T4 >
inline NO_INLINE void collect_paired_args(std::vector<std::pair<T1, T2>> &collected_args,
const T3 &a1, const T4 &a2) {
collected_args.push_back(std::pair<T1, T2>(a1, a2));
}
template <typename T1, typename T2, typename T3, typename T4, typename ...Args>
inline NO_INLINE void collect_paired_args(std::vector<std::pair<T1, T2>> &collected_args,
const T3 &a1, const T4 &a2, Args&&... args) {
collected_args.push_back(std::pair<T1, T2>(a1, a2));
collect_paired_args(collected_args, std::forward<Args>(args)...);
}
template<typename... T>
struct meta_and : std::true_type {};
template<typename T1, typename... Args>
struct meta_and<T1, Args...> : std::integral_constant<bool, T1::value && meta_and<Args...>::value> {};
template<typename... T>
struct meta_or : std::false_type {};
template<typename T1, typename... Args>
struct meta_or<T1, Args...> : std::integral_constant<bool, T1::value || meta_or<Args...>::value> {};
template<typename To, typename... Args>
struct all_are_convertible : meta_and<std::is_convertible<Args, To>...> {};
EXPORT std::string extract_namespaces(const std::string &name, std::vector<std::string> &namespaces);
struct FileStat {
uint64_t file_size;
uint32_t mod_time;
uint32_t uid;
uint32_t gid;
uint32_t mode;
};
EXPORT std::string file_make_temp(const std::string &prefix, const std::string &suffix);
EXPORT std::string dir_make_temp();
EXPORT bool file_exists(const std::string &name);
EXPORT void assert_file_exists(const std::string &name);
EXPORT void assert_no_file_exists(const std::string &name);
EXPORT void file_unlink(const std::string &name);
EXPORT void file_unlink(const std::string &name);
EXPORT void ensure_no_file_exists(const std::string &name);
EXPORT void dir_rmdir(const std::string &name);
EXPORT FileStat file_stat(const std::string &name);
class TemporaryFile final {
public:
TemporaryFile(const std::string &prefix, const std::string &suffix)
: temp_path(file_make_temp(prefix, suffix)) {}
const std::string &pathname() const { return temp_path; }
~TemporaryFile() { file_unlink(temp_path); }
private:
const std::string temp_path;
TemporaryFile(const TemporaryFile &) = delete;
void operator=(const TemporaryFile &) = delete;
};
bool add_would_overflow(int bits, int64_t a, int64_t b);
bool sub_would_overflow(int bits, int64_t a, int64_t b);
bool mul_would_overflow(int bits, int64_t a, int64_t b);
#if __cplusplus >= 201402L
using std::integer_sequence;
using std::make_integer_sequence;
using std::index_sequence;
using std::make_index_sequence;
#else
template<typename T, T... Ints>
struct integer_sequence {
static constexpr size_t size() { return sizeof...(Ints); }
};
template<typename T>
struct next_integer_sequence;
template<typename T, T... Ints>
struct next_integer_sequence<integer_sequence<T, Ints...>> {
using type = integer_sequence<T, Ints..., sizeof...(Ints)>;
};
template<typename T, T I, T N>
struct make_integer_sequence_helper {
using type = typename next_integer_sequence<
typename make_integer_sequence_helper<T, I+1, N>::type
>::type;
};
template<typename T, T N>
struct make_integer_sequence_helper<T, N, N> {
using type = integer_sequence<T>;
};
template<typename T, T N>
using make_integer_sequence = typename make_integer_sequence_helper<T, 0, N>::type;
template<size_t... Ints>
using index_sequence = integer_sequence<size_t, Ints...>;
template<size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
#endif
}
}
#endif