Loading...
Searching...
No Matches
string_storage.h
Go to the documentation of this file.
#ifndef HALIDE_RUNTIME_STRING_STORAGE_H
#define HALIDE_RUNTIME_STRING_STORAGE_H
#include "../HalideRuntime.h"
#include "block_storage.h"
namespace Halide {
namespace Runtime {
namespace Internal {
// Static utility functions for dealing with string data
struct StringUtils {
static bool is_empty(const char *str) {
if (str == nullptr) {
return true;
}
if (str[0] == '\0') {
return true;
}
return false;
}
// count the number of delimited string tokens
static size_t count_tokens(const char *str, const char *delim) {
if (StringUtils::is_empty(str)) {
return 0;
}
if (StringUtils::is_empty(delim)) {
return 1;
} // no delim ... string is one token
size_t count = 0;
const char *ptr = str;
size_t delim_length = strlen(delim);
while (!StringUtils::is_empty(ptr)) {
const char *next_delim = strstr(ptr, delim);
ptr = (next_delim != nullptr) ? (next_delim + delim_length) : nullptr;
++count;
}
return count;
}
// retuns true if s1 contains s2 (within n characters)
static bool contains(const char *s1, const char *s2, size_t n) {
if (is_empty(s2)) {
return true;
} // s2 is empty ... return true to match strstr
char starts_with = *s2;
for (size_t length = strlen(s2); length <= n; n--, s1++) {
if (*s1 == starts_with) {
for (size_t i = 1; i <= length; i++) {
if (i == length) {
return true;
}
if (s1[i] != s2[i]) {
break;
}
}
}
}
return false;
}
static size_t count_length(const char *str, size_t max_chars) {
const char *ptr = str;
while (!StringUtils::is_empty(ptr) && ((size_t(ptr - str)) < max_chars)) {
++ptr;
}
return size_t(ptr - str);
}
static size_t copy_up_to(char *dst, const char *src, size_t max_chars) {
size_t length = count_length(src, max_chars);
memcpy(dst, src, length);
dst[length] = '\0';
return length;
}
};
// --
// Storage class for handling c-string data (based on block storage)
// -- Intended for building and maintaining string data w/8-bit chars
//
class StringStorage {
public:
explicit StringStorage(void *user_context = nullptr, uint32_t capacity = 0, const SystemMemoryAllocatorFns &sma = default_allocator());
StringStorage(const StringStorage &other) = default;
~StringStorage();
// Factory methods for creation / destruction
static StringStorage *create(void *user_context, const SystemMemoryAllocatorFns &ma);
static void destroy(void *user_context, StringStorage *string_storage);
void initialize(void *user_context, uint32_t capacity = 0, const SystemMemoryAllocatorFns &sma = default_allocator());
void destroy(void *user_context);
StringStorage &operator=(const StringStorage &other);
bool operator==(const StringStorage &other) const;
bool operator!=(const StringStorage &other) const;
bool contains(const char *str) const;
bool contains(const StringStorage &other) const;
void reserve(void *user_context, size_t length);
void assign(void *user_context, char ch);
void assign(void *user_context, const char *str, size_t length = 0); // if length is zero, strlen is used
void append(void *user_context, char ch);
void append(void *user_context, const char *str, size_t length = 0); // if length is zero, strlen is used
void prepend(void *user_context, char ch);
void prepend(void *user_context, const char *str, size_t length = 0); // if length is zero, strlen is used
void clear(void *user_context);
void terminate(void *user_context, size_t length);
size_t length() const;
const char *data() const;
const SystemMemoryAllocatorFns &current_allocator() const;
static const SystemMemoryAllocatorFns &default_allocator();
private:
BlockStorage contents;
};
StringStorage::StringStorage(void *user_context, uint32_t capacity, const SystemMemoryAllocatorFns &sma)
: contents(user_context, {sizeof(char), 32, 32}, sma) {
if (capacity) {
contents.reserve(user_context, capacity);
}
}
StringStorage::~StringStorage() {
destroy(nullptr);
}
StringStorage *StringStorage::create(void *user_context, const SystemMemoryAllocatorFns &system_allocator) {
halide_abort_if_false(user_context, system_allocator.allocate != nullptr);
StringStorage *result = reinterpret_cast<StringStorage *>(
system_allocator.allocate(user_context, sizeof(StringStorage)));
if (result == nullptr) {
halide_error(user_context, "StringStorage: Failed to create instance! Out of memory!\n");
return nullptr;
}
result->initialize(user_context, 32, system_allocator);
return result;
}
void StringStorage::destroy(void *user_context, StringStorage *instance) {
halide_abort_if_false(user_context, instance != nullptr);
SystemMemoryAllocatorFns system_allocator = instance->current_allocator();
instance->destroy(user_context);
halide_abort_if_false(user_context, system_allocator.deallocate != nullptr);
system_allocator.deallocate(user_context, instance);
}
StringStorage &StringStorage::operator=(const StringStorage &other) {
if (&other != this) {
assign(nullptr, other.data(), other.length());
}
return *this;
}
bool StringStorage::contains(const char *str) const {
if (contents.empty()) {
return false;
}
const char *this_str = static_cast<const char *>(contents.data());
return StringUtils::contains(this_str, str, contents.size());
}
bool StringStorage::contains(const StringStorage &other) const {
if (contents.empty()) {
return false;
}
if (other.contents.empty()) {
return false;
}
const char *this_str = static_cast<const char *>(contents.data());
const char *other_str = static_cast<const char *>(other.contents.data());
return StringUtils::contains(this_str, other_str, contents.size());
}
bool StringStorage::operator==(const StringStorage &other) const {
if (contents.size() != other.contents.size()) {
return false;
}
const char *this_str = static_cast<const char *>(contents.data());
const char *other_str = static_cast<const char *>(other.contents.data());
return strncmp(this_str, other_str, contents.size()) == 0;
}
bool StringStorage::operator!=(const StringStorage &other) const {
return !(*this == other);
}
void StringStorage::reserve(void *user_context, size_t length) {
contents.reserve(user_context, length + 1); // leave room for termination
contents.resize(user_context, length, false);
terminate(user_context, length);
}
void StringStorage::assign(void *user_context, char ch) {
reserve(user_context, 1);
char *ptr = static_cast<char *>(contents[0]);
(*ptr) = ch;
terminate(user_context, 1);
}
void StringStorage::assign(void *user_context, const char *str, size_t length) {
if (StringUtils::is_empty(str)) {
return;
}
if (length == 0) {
length = strlen(str);
}
reserve(user_context, length);
contents.replace(user_context, 0, str, length);
terminate(user_context, length);
}
void StringStorage::append(void *user_context, const char *str, size_t length) {
if (StringUtils::is_empty(str)) {
return;
}
if (length == 0) {
length = strlen(str);
}
const size_t old_length = StringUtils::count_length(data(), contents.size());
size_t new_length = old_length + length;
reserve(user_context, new_length);
contents.insert(user_context, old_length, str, length);
terminate(user_context, new_length);
}
void StringStorage::append(void *user_context, char ch) {
const size_t old_length = StringUtils::count_length(data(), contents.size());
size_t new_length = old_length + 1;
reserve(user_context, new_length);
contents.insert(user_context, old_length, &ch, 1);
terminate(user_context, new_length);
}
void StringStorage::prepend(void *user_context, const char *str, size_t length) {
if (StringUtils::is_empty(str)) {
return;
}
if (length == 0) {
length = strlen(str);
}
const size_t old_length = StringUtils::count_length(data(), contents.size());
size_t new_length = old_length + length;
reserve(user_context, new_length);
contents.insert(user_context, 0, str, length);
terminate(user_context, new_length);
}
void StringStorage::prepend(void *user_context, char ch) {
const size_t old_length = StringUtils::count_length(data(), contents.size());
size_t new_length = old_length + 1;
reserve(user_context, new_length);
contents.prepend(user_context, &ch);
terminate(user_context, new_length);
}
void StringStorage::terminate(void *user_context, size_t length) {
if (contents.is_valid(length)) {
char *end_ptr = static_cast<char *>(contents[length]);
(*end_ptr) = '\0';
} else {
halide_error(user_context, "StringStorage: Failed to terminate string! Out of bounds!\n");
}
}
void StringStorage::clear(void *user_context) {
contents.clear(user_context);
terminate(user_context, 0);
}
void StringStorage::initialize(void *user_context, uint32_t capacity, const SystemMemoryAllocatorFns &sma) {
contents.initialize(user_context, {sizeof(char), 32, 32}, sma);
reserve(user_context, capacity);
terminate(user_context, 0);
}
void StringStorage::destroy(void *user_context) {
contents.destroy(user_context);
}
size_t StringStorage::length() const {
return StringUtils::count_length(data(), contents.size());
}
const char *StringStorage::data() const {
return static_cast<const char *>(contents.data());
}
const SystemMemoryAllocatorFns &
StringStorage::current_allocator() const {
return contents.current_allocator();
}
const SystemMemoryAllocatorFns &
StringStorage::default_allocator() {
return BlockStorage::default_allocator();
}
// --
} // namespace Internal
} // namespace Runtime
} // namespace Halide
#endif // HALIDE_RUNTIME_STRING_STORAGE_H
HalideRuntime.h
This file declares the routines used by Halide internally in its runtime.
halide_error
void halide_error(void *user_context, const char *)
Halide calls this function on runtime errors (for example bounds checking failures).
block_storage.h
Halide::Runtime::Internal::BlockStorage
Definition block_storage.h:18
Halide::Runtime::Internal::BlockStorage::size
size_t size() const
Definition block_storage.h:336
Halide::Runtime::Internal::BlockStorage::data
void * data()
Definition block_storage.h:354
Halide::Runtime::Internal::BlockStorage::default_allocator
static const SystemMemoryAllocatorFns & default_allocator()
Definition block_storage.h:429
Halide::Runtime::Internal::BlockStorage::empty
bool empty() const
Definition block_storage.h:324
Halide::Runtime::Internal::StringStorage::current_allocator
const SystemMemoryAllocatorFns & current_allocator() const
Definition string_storage.h:299
Halide::Runtime::Internal::StringStorage::assign
void assign(void *user_context, char ch)
Definition string_storage.h:203
Halide::Runtime::Internal::StringStorage::prepend
void prepend(void *user_context, char ch)
Definition string_storage.h:258
Halide::Runtime::Internal::StringStorage::StringStorage
StringStorage(void *user_context=nullptr, uint32_t capacity=0, const SystemMemoryAllocatorFns &sma=default_allocator())
Definition string_storage.h:124
Halide::Runtime::Internal::StringStorage::operator=
StringStorage & operator=(const StringStorage &other)
Definition string_storage.h:157
Halide::Runtime::Internal::StringStorage::default_allocator
static const SystemMemoryAllocatorFns & default_allocator()
Definition string_storage.h:304
Halide::Runtime::Internal::StringStorage::operator==
bool operator==(const StringStorage &other) const
Definition string_storage.h:184
Halide::Runtime::Internal::StringStorage::data
const char * data() const
Definition string_storage.h:294
Halide::Runtime::Internal::StringStorage::reserve
void reserve(void *user_context, size_t length)
Definition string_storage.h:197
Halide::Runtime::Internal::StringStorage::~StringStorage
~StringStorage()
Definition string_storage.h:131
Halide::Runtime::Internal::StringStorage::operator!=
bool operator!=(const StringStorage &other) const
Definition string_storage.h:193
Halide::Runtime::Internal::StringStorage::length
size_t length() const
Definition string_storage.h:290
Halide::Runtime::Internal::StringStorage::StringStorage
StringStorage(const StringStorage &other)=default
Halide::Runtime::Internal::StringStorage::initialize
void initialize(void *user_context, uint32_t capacity=0, const SystemMemoryAllocatorFns &sma=default_allocator())
Definition string_storage.h:280
Halide::Runtime::Internal::StringStorage::create
static StringStorage * create(void *user_context, const SystemMemoryAllocatorFns &ma)
Definition string_storage.h:135
Halide::Runtime::Internal::StringStorage::contains
bool contains(const char *str) const
Definition string_storage.h:164
Halide::Runtime::Internal::StringStorage::clear
void clear(void *user_context)
Definition string_storage.h:275
Halide::Runtime::Internal::StringStorage::append
void append(void *user_context, char ch)
Definition string_storage.h:236
Halide::Runtime::Internal::StringStorage::terminate
void terminate(void *user_context, size_t length)
Definition string_storage.h:266
Halide::Runtime::Internal::StringStorage::destroy
static void destroy(void *user_context, StringStorage *string_storage)
Definition string_storage.h:149
Halide::Runtime::Internal
Definition constants.h:13
Halide::Runtime::Internal::strlen
size_t strlen(const char *string)
Halide::Runtime
Definition constants.h:12
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition AbstractGenerator.h:19
strncmp
int strncmp(const char *s, const char *t, size_t n)
memcpy
void * memcpy(void *s1, const void *s2, size_t n)
size_t
__SIZE_TYPE__ size_t
Definition runtime_internal.h:31
uint32_t
unsigned __INT32_TYPE__ uint32_t
Definition runtime_internal.h:25
halide_abort_if_false
#define halide_abort_if_false(user_context, cond)
Definition runtime_internal.h:271
strstr
const char * strstr(const char *, const char *)
Halide::Runtime::Internal::StringUtils
Definition string_storage.h:12
Halide::Runtime::Internal::StringUtils::count_tokens
static size_t count_tokens(const char *str, const char *delim)
Definition string_storage.h:24
Halide::Runtime::Internal::StringUtils::contains
static bool contains(const char *s1, const char *s2, size_t n)
Definition string_storage.h:44
Halide::Runtime::Internal::StringUtils::count_length
static size_t count_length(const char *str, size_t max_chars)
Definition string_storage.h:64
Halide::Runtime::Internal::StringUtils::is_empty
static bool is_empty(const char *str)
Definition string_storage.h:13
Halide::Runtime::Internal::StringUtils::copy_up_to
static size_t copy_up_to(char *dst, const char *src, size_t max_chars)
Definition string_storage.h:72
Halide::Runtime::Internal::SystemMemoryAllocatorFns
Definition memory_resources.h:193
Halide::Runtime::Internal::SystemMemoryAllocatorFns::deallocate
DeallocateSystemFn deallocate
Definition memory_resources.h:195
Halide::Runtime::Internal::SystemMemoryAllocatorFns::allocate
AllocateSystemFn allocate
Definition memory_resources.h:194