<commit_before>#ifndef HALIDE_BUFFER_H
#define HALIDE_BUFFER_H

#include "runtime/HalideBuffer.h"
#include "IntrusivePtr.h"
#include "Expr.h"
#include "Util.h"
#include "DeviceInterface.h"

namespace Halide {

template<typename T = void> class Buffer;

namespace Internal {

struct BufferContents {
    mutable RefCount ref_count;
    std::string name;
    Runtime::Buffer<> buf;
};

EXPORT Expr buffer_accessor(const Buffer<> &buf, const std::vector<Expr> &args);

template<typename ...Args>
struct all_ints_and_optional_name : std::false_type {};

template<typename First, typename ...Rest>
struct all_ints_and_optional_name<First, Rest...> :
        meta_and<std::is_convertible<First, int>,
                 all_ints_and_optional_name<Rest...>> {};

template<typename T> struct all_ints_and_optional_name<T> :
        meta_or<std::is_convertible<T, std::string>,
                std::is_convertible<T, int>> {};

template<> struct all_ints_and_optional_name<> : std::true_type {};

template<typename T,
         typename = typename std::enable_if<!std::is_convertible<T, std::string>::value>::type>
std::string get_name_from_end_of_parameter_pack(T&&) {
    return "";
}

inline std::string get_name_from_end_of_parameter_pack(const std::string &n) {
    return n;
}

inline std::string get_name_from_end_of_parameter_pack() {
    return "";
}

template<typename First,
         typename Second,
         typename ...Args>
std::string get_name_from_end_of_parameter_pack(First first, Second second, Args&&... rest) {
    return get_name_from_end_of_parameter_pack(second, std::forward<Args>(rest)...);
}

inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &, const std::string &) {
}

inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &) {
}

template<typename ...Args>
void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &result, int x, Args&&... rest) {
    result.push_back(x);
    get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(rest)...);
}


template<typename ...Args>
std::vector<int> get_shape_from_start_of_parameter_pack(Args&&... args) {
    std::vector<int> result;
    get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(args)...);
    return result;
}

template<typename T, typename T2>
using add_const_if_T_is_const = typename std::conditional<std::is_const<T>::value, const T2, T2>::type;

}

/** A Halide::Buffer is a named shared reference to a
 * Halide::Runtime::Buffer.
 *
 * A Buffer<T1> can refer to a Buffer<T2> if T1 is const whenever T2
 * is const, and either T1 = T2 or T1 is void. A Buffer<void> can
 * refer to any Buffer of any non-const type, and the default
 * template parameter is T = void.
 */
template<typename T>
class Buffer {
    Internal::IntrusivePtr<Internal::BufferContents> contents;

    template<typename T2> friend class Buffer;

    template<typename T2>
    static void assert_can_convert_from(const Buffer<T2> &other) {
        Runtime::Buffer<T>::assert_can_convert_from(*(other.get()));
    }

public:

    typedef T ElemType;

    /** Make a null Buffer, which points to no Runtime::Buffer */
    Buffer() {}

    /** Make a Buffer from a Buffer of a different type */
    template<typename T2>
    Buffer(const Buffer<T2> &other) :
        contents(other.contents) {
        assert_can_convert_from(other);
    }

    /** Move construct from a Buffer of a different type */
    template<typename T2>
    Buffer(Buffer<T2> &&other) {
        assert_can_convert_from(other);
        contents = std::move(other.contents);
    }

    /** Construct a Buffer that captures and owns an rvalue Runtime::Buffer */
    template<int D>
    Buffer(Runtime::Buffer<T, D> &&buf, const std::string &name = "") :
        contents(new Internal::BufferContents) {
        contents->buf = std::move(buf);
        if (name.empty()) {
            contents->name = Internal::make_entity_name(this, "Halide::Buffer<?", 'b');
        } else {
            contents->name = name;
        }
    }

    /** Constructors that match Runtime::Buffer with two differences:
     * 1) They take a Type instead of a halide_type_t
     * 2) There is an optional last string argument that gives the buffer a specific name
     */
    // @{
    template<typename ...Args,
             typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
    explicit Buffer(Type t,
                    int first, Args... rest) :
        Buffer(Runtime::Buffer<T>(t, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
               Internal::get_name_from_end_of_parameter_pack(rest...)) {}

    explicit Buffer(const halide_buffer_t &buf,
                    const std::string &name = "") :
        Buffer(Runtime::Buffer<T>(buf), name) {}

    template<typename ...Args,
             typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
    explicit Buffer(int first, Args... rest) :
        Buffer(Runtime::Buffer<T>(Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
               Internal::get_name_from_end_of_parameter_pack(rest...)) {}

    explicit Buffer(Type t,<commit_msg>Add legacy buffer_t constructor to Halide::Buffer<commit_after>#ifndef HALIDE_BUFFER_H
#define HALIDE_BUFFER_H

#include "runtime/HalideBuffer.h"
#include "IntrusivePtr.h"
#include "Expr.h"
#include "Util.h"
#include "DeviceInterface.h"

namespace Halide {

template<typename T = void> class Buffer;

namespace Internal {

struct BufferContents {
    mutable RefCount ref_count;
    std::string name;
    Runtime::Buffer<> buf;
};

EXPORT Expr buffer_accessor(const Buffer<> &buf, const std::vector<Expr> &args);

template<typename ...Args>
struct all_ints_and_optional_name : std::false_type {};

template<typename First, typename ...Rest>
struct all_ints_and_optional_name<First, Rest...> :
        meta_and<std::is_convertible<First, int>,
                 all_ints_and_optional_name<Rest...>> {};

template<typename T> struct all_ints_and_optional_name<T> :
        meta_or<std::is_convertible<T, std::string>,
                std::is_convertible<T, int>> {};

template<> struct all_ints_and_optional_name<> : std::true_type {};

template<typename T,
         typename = typename std::enable_if<!std::is_convertible<T, std::string>::value>::type>
std::string get_name_from_end_of_parameter_pack(T&&) {
    return "";
}

inline std::string get_name_from_end_of_parameter_pack(const std::string &n) {
    return n;
}

inline std::string get_name_from_end_of_parameter_pack() {
    return "";
}

template<typename First,
         typename Second,
         typename ...Args>
std::string get_name_from_end_of_parameter_pack(First first, Second second, Args&&... rest) {
    return get_name_from_end_of_parameter_pack(second, std::forward<Args>(rest)...);
}

inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &, const std::string &) {
}

inline void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &) {
}

template<typename ...Args>
void get_shape_from_start_of_parameter_pack_helper(std::vector<int> &result, int x, Args&&... rest) {
    result.push_back(x);
    get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(rest)...);
}


template<typename ...Args>
std::vector<int> get_shape_from_start_of_parameter_pack(Args&&... args) {
    std::vector<int> result;
    get_shape_from_start_of_parameter_pack_helper(result, std::forward<Args>(args)...);
    return result;
}

template<typename T, typename T2>
using add_const_if_T_is_const = typename std::conditional<std::is_const<T>::value, const T2, T2>::type;

}

/** A Halide::Buffer is a named shared reference to a
 * Halide::Runtime::Buffer.
 *
 * A Buffer<T1> can refer to a Buffer<T2> if T1 is const whenever T2
 * is const, and either T1 = T2 or T1 is void. A Buffer<void> can
 * refer to any Buffer of any non-const type, and the default
 * template parameter is T = void.
 */
template<typename T>
class Buffer {
    Internal::IntrusivePtr<Internal::BufferContents> contents;

    template<typename T2> friend class Buffer;

    template<typename T2>
    static void assert_can_convert_from(const Buffer<T2> &other) {
        Runtime::Buffer<T>::assert_can_convert_from(*(other.get()));
    }

public:

    typedef T ElemType;

    /** Make a null Buffer, which points to no Runtime::Buffer */
    Buffer() {}

    /** Make a Buffer from a Buffer of a different type */
    template<typename T2>
    Buffer(const Buffer<T2> &other) :
        contents(other.contents) {
        assert_can_convert_from(other);
    }

    /** Move construct from a Buffer of a different type */
    template<typename T2>
    Buffer(Buffer<T2> &&other) {
        assert_can_convert_from(other);
        contents = std::move(other.contents);
    }

    /** Construct a Buffer that captures and owns an rvalue Runtime::Buffer */
    template<int D>
    Buffer(Runtime::Buffer<T, D> &&buf, const std::string &name = "") :
        contents(new Internal::BufferContents) {
        contents->buf = std::move(buf);
        if (name.empty()) {
            contents->name = Internal::make_entity_name(this, "Halide::Buffer<?", 'b');
        } else {
            contents->name = name;
        }
    }

    /** Constructors that match Runtime::Buffer with two differences:
     * 1) They take a Type instead of a halide_type_t
     * 2) There is an optional last string argument that gives the buffer a specific name
     */
    // @{
    template<typename ...Args,
             typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
    explicit Buffer(Type t,
                    int first, Args... rest) :
        Buffer(Runtime::Buffer<T>(t, Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
               Internal::get_name_from_end_of_parameter_pack(rest...)) {}

    explicit Buffer(const halide_buffer_t &buf,
                    const std::string &name = "") :
        Buffer(Runtime::Buffer<T>(buf), name) {}

    explicit Buffer(const buffer_t &buf,
                    const std::string &name = "") :
        Buffer(Runtime::Buffer<T>(buf), name) {}

    template<typename ...Args,
             typename = typename std::enable_if<Internal::all_ints_and_optional_name<Args...>::value>::type>
    explicit Buffer(int first, Args... rest) :
        Buffer(Runtime::Buffer<T>(Internal::get_shape_from_start_of_parameter_pack(first, rest...)),
               Internal::get_name_from_end_of_parameter_pack(rest...)) {}

    explicit Buffer(Type t,
{'fraction_non_alphanumeric': 0.13035697466327587, 'fraction_numerical': 0.0035791654893095977, 'mean_word_length': 3.8219800181653043, 'pattern_counts': {'":': 0, '<': 122, '<?xml version=': 0, '>': 126, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3654085', 'n_tokens_mistral': 3345, 'n_tokens_neox': 3271, 'n_words': 745}