<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Copyright (c) 2017, <NAME> <<EMAIL>> */

#pragma once

#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

#include <deai/compiler.h>
#include <deai/object.h>
#include "common.h"

static inline void typed_alloc_copy(di_type_t type, const void *src, void **dest) {
	void *ret = calloc(1, di_sizeof_type(type));
	memcpy(ret, src, di_sizeof_type(type));
	*dest = ret;
}

static inline int
integer_conversion(di_type_t inty, const void *inp, di_type_t outty, void **outp, bool *cloned) {
	*cloned = false;
	if (inty == outty) {
		*outp = (void *)inp;
		return 0;
	}

#define convert_case(srct, dstt, dstmax, dstmin)                                         \
	case di_typeof((srct)0):                                                         \
		do {                                                                     \
			srct tmp = *(srct *)(inp);                                       \
			if (tmp > (dstmax) || tmp < (dstmin)) {                          \
				*outp = NULL;                                            \
				return -ERANGE;                                          \
			}                                                                \
			dstt *tmp2 = malloc(sizeof(dstt));                               \
			*tmp2 = (dstt)tmp;                                               \
			*outp = tmp2;                                                    \
		} while (0);                                                             \
		break

#define convert_switch(s1, s2, s3, ...)                                                  \
	switch (inty) {                                                                  \
		convert_case(s1, __VA_ARGS__);                                           \
		convert_case(s2, __VA_ARGS__);                                           \
		convert_case(s3, __VA_ARGS__);                                           \
	default:                                                                         \
		*outp = NULL;                                                            \
		return -EINVAL;                                                          \
	}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
	switch (outty) {
	case DI_TYPE_INT:
		convert_switch(unsigned int, int, uint64_t, int64_t, INT64_MAX, INT64_MIN);
		break;
	case DI_TYPE_NINT:
		convert_switch(unsigned int, uint64_t, int64_t, int, INT_MAX, INT_MIN);
		break;
	case DI_TYPE_UINT:
		convert_switch(unsigned int, int, int64_t, uint64_t, UINT64_MAX, 0);
		break;
	case DI_TYPE_NUINT:
		convert_switch(int, int64_t, uint64_t, unsigned int, UINT_MAX, 0);
		break;
	default:
		*outp = NULL;
		return -EINVAL;
	}
#pragma GCC diagnostic pop

#undef convert_case
#undef convert_switch
	*cloned = true;
	return 0;
}

static inline bool is_integer(di_type_t t) {
	return t == DI_TYPE_INT || t == DI_TYPE_NINT || t == DI_TYPE_UINT || t == DI_TYPE_NUINT;
}

/// Convert value `inp` to type `outty`. `*outp != inp` if and only if a conversion
/// happened. And if a conversion did happen, it's safe to free the original value.
///
/// @param[out] cloned if false, value in `outp` is borrowed from `inp`. otherwise the
///                    value is cloned. always false in case of an error
static inline int unused di_type_conversion(di_type_t inty, const void *inp,
                                            di_type_t outty, void **outp, bool *cloned) {
	*cloned = false;
	if (inty == outty) {
		*outp = (void *)inp;
		return 0;<commit_msg>utils.h: add string -> string literal conversion<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Copyright (c) 2017, <NAME> <<EMAIL>> */

#pragma once

#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

#include <deai/compiler.h>
#include <deai/object.h>
#include "common.h"

static inline void typed_alloc_copy(di_type_t type, const void *src, void **dest) {
	void *ret = calloc(1, di_sizeof_type(type));
	memcpy(ret, src, di_sizeof_type(type));
	*dest = ret;
}

static inline int
integer_conversion(di_type_t inty, const void *inp, di_type_t outty, void **outp, bool *cloned) {
	*cloned = false;
	if (inty == outty) {
		*outp = (void *)inp;
		return 0;
	}

#define convert_case(srct, dstt, dstmax, dstmin)                                         \
	case di_typeof((srct)0):                                                         \
		do {                                                                     \
			srct tmp = *(srct *)(inp);                                       \
			if (tmp > (dstmax) || tmp < (dstmin)) {                          \
				*outp = NULL;                                            \
				return -ERANGE;                                          \
			}                                                                \
			dstt *tmp2 = malloc(sizeof(dstt));                               \
			*tmp2 = (dstt)tmp;                                               \
			*outp = tmp2;                                                    \
		} while (0);                                                             \
		break

#define convert_switch(s1, s2, s3, ...)                                                  \
	switch (inty) {                                                                  \
		convert_case(s1, __VA_ARGS__);                                           \
		convert_case(s2, __VA_ARGS__);                                           \
		convert_case(s3, __VA_ARGS__);                                           \
	default:                                                                         \
		*outp = NULL;                                                            \
		return -EINVAL;                                                          \
	}

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
	switch (outty) {
	case DI_TYPE_INT:
		convert_switch(unsigned int, int, uint64_t, int64_t, INT64_MAX, INT64_MIN);
		break;
	case DI_TYPE_NINT:
		convert_switch(unsigned int, uint64_t, int64_t, int, INT_MAX, INT_MIN);
		break;
	case DI_TYPE_UINT:
		convert_switch(unsigned int, int, int64_t, uint64_t, UINT64_MAX, 0);
		break;
	case DI_TYPE_NUINT:
		convert_switch(int, int64_t, uint64_t, unsigned int, UINT_MAX, 0);
		break;
	default:
		*outp = NULL;
		return -EINVAL;
	}
#pragma GCC diagnostic pop

#undef convert_case
#undef convert_switch
	*cloned = true;
	return 0;
}

static inline bool is_integer(di_type_t t) {
	return t == DI_TYPE_INT || t == DI_TYPE_NINT || t == DI_TYPE_UINT || t == DI_TYPE_NUINT;
}

/// Convert value `inp` to type `outty`. `*outp != inp` if and only if a conversion
/// happened. And if a conversion did happen, it's safe to free the original value.
///
/// @param[out] cloned if false, value in `outp` is borrowed from `inp`. otherwise the
///                    value is cloned. always false in case of an error
static inline int unused di_type_conversion(di_type_t inty, const void *inp,
                                            di_type_t outty, void **outp, bool *cloned) {
	*cloned = false;
	if (inty == outty) {
		*outp = (void *)inp;
		return 0;
	}

	if (inty == DI_TYPE_STRING && outty == DI_TYPE_STRING_LITERAL) {
		*outp = (void *)inp;
		return 0;
{'fraction_non_alphanumeric': 0.10257400257400258, 'fraction_numerical': 0.012226512226512226, 'mean_word_length': 1.3706528370957902, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 68, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6017856', 'n_tokens_mistral': 2349, 'n_tokens_neox': 2189, 'n_words': 638}