<commit_before>/*

Copyright (c) 2014 <NAME> <<EMAIL>>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

*/

#ifndef __DST_DYNAMIC_ARRAY_H__
#define __DST_DYNAMIC_ARRAY_H__

#include <dstConfig.h>
#include <dstRandom.h>

#include <stdio.h>
#include <signal.h>

// Dynamic array template class allows any type of data.
// T is the type of the stored data.
// S is the integer type for the size of the array (normally int, allowing for
// 2G (2^31) entries, but for small arrays unsigned short/uint16_t (max 32768 entries)
// or especially unsigned char (max 128 entries) can save a little space, especially when
// lots of very small arrays are expected.

template <class T, class S>
class DST_API dstDynamicArrayBaseClass {
private :
	T *data;
	S nu_elements;
	S max_elements;

	// By how much to expand the array.
	virtual inline S GetExpansionHint(S capacity) const = 0;
	// The absolute maximum capacity allowed by the class variant.
        inline void ResizeCapacity(S new_capacity) {
                max_elements = new_capacity;
		data = (T *)realloc(data, sizeof(T) * max_elements);
	}
	inline void ExpandCapacity() {
		S new_capacity = GetExpansionHint(max_elements);
		if (new_capacity < max_elements) {
			// When new_capacity is less than max_elements, usually zero,
			// the maximum capacity has been reached, so the element cannot be
			// added. Exit with an error message.
			fprintf(stderr, "dstDynamicArray: maximum array capacity overflow\n");
			raise(SIGABRT);
		}
		ResizeCapacity(new_capacity);
        }

public :
	virtual inline S MaxCapacity() const = 0;
	dstDynamicArrayBaseClass() {
		nu_elements = 0;
		max_elements = 0;
		data = NULL;
	}
	dstDynamicArrayBaseClass(S starting_capacity) {
		nu_elements = 0;
		data = NULL;
		ResizeCapacity(starting_capacity);
	}
        // There is no deconstuctor. Run FreeData() or MakeEmpty() to free storage space.
	inline void FreeData() const {
		free(data);
        }
	inline void MakeEmpty() {
		FreeData();
		nu_elements = 0;
		max_elements = 0;
		data = NULL;	
	}
	inline S Size() const {
		return nu_elements;
	}
	inline S AllocatedSize() const {
		return max_elements;
        }
	// Get value of element i.
	inline T Get(S i) const {
		return data[i];
	}
        // Set value of element i.
        inline void Set(S i, T v) {
		data[i] = v;
        }
	// Get a pointer to the start of the array.
	inline T *DataPointer() const {
                return data;
        }
	// Get a pointer to a specific element.
        inline T *DataPointer(S i) const {
		return &data[i];
        }
        // Trim capacity to the number of elements. This may result in a unusual
	// (e.g. non-power of two) capacity.
	inline void TrimCapacity() {
		ResizeCapacity(nu_elements);
	}
	// Set the maximum capacity to a specific size.
        inline void SetCapacity(S capacity) {
		ResizeCapacity(capacity);
	}
        // Truncate array to n elements. Capacity remains the same. n must be less or equal
	// to the current number of elements as reported by Size().
	inline void Truncate(S n) {
		nu_elements = n;
        }
	// Add element with value V.
	inline void Add(T v) {
		if (nu_elements == max_elements)
			ExpandCapacity();
		data[nu_elements] = v;
		nu_elements++;
	}
};

// Standard implementation of the class, which doubles the capacity each time
// the array is full.

template <class T, class S>
class DST_API dstDynamicArray : public dstDynamicArrayBaseClass <T, S> {
public :
	dstDynamicArray(S starting_capacity = 4) { }
	// The absolute maximum capacity allowed by the class variant.
	inline S MaxCapacity() const {
		return (S)1 << (sizeof(S) * 8 - 1);
	}

private :
	// By how much to expand the array.
	inline S GetExpansionHint(S size) const {
		// Expand the size to the next power of two.
                uint32_t log2_size = dstCalculateLog2(size);
		return (S)((S)1 << (log2_size + 1));
	}
};

// Template class to cast DynamicArray class type to another, same-sized type.
// U is the new type, T is the same-sized type for which an existing class exists,
// S is the integer type for the size storage (usually uint32_t), and C2 is the name
// of the existing class.

template <class U, class T, class S, class C2>
class DST_API dstCastDynamicArray : public C2 {
public :
	dstCastDynamicArray(S starting_capacity = 4) { }
	// Get value of element i.
	inline U Get(S i) const {
		return (U)((C2 *)this->Get(i));
	}
        // Set value of element i.
        inline void Set(S i, U v) const {
		((C2 *)this)->Set(i, (T)v);
        }
	// Get a pointer to the start of the array.
	inline U *DataPointer() const {
                return (U *)((C2 *)this->DataPointer());
        }
	// Get a pointer to a specific element.
        inline U *DataPointer(uint32_t i) const {
		return &(U *)((C2 *)this->DataPointer(i));
        }
	inline void Add(U s) {
		((C2 *)this)->Add((T)s);
	}
};

// Dynamic array types for int, int64_t, void * char *, with a size storage size
// of 32 bits (max 2G entries).
typedef dstDynamicArray <int, uint32_t> dstIntArray;
typedef dstDynamicArray <int64_t, uint32_t> dstInt64Array;
#if UINTPTR_MAX == 0xFFFFFFFF
// 32-bit pointers.
typedef dstCastDynamicArray <void *, int, uint32_t, dstIntArray> dstPointerArray;
#else
// 64-bit pointers
typedef dstCastDynamicArray <void *, int64_t, uint32_t, dstInt64Array> dstPointerArray;
#endif
typedef dstCastDynamicArray <char *, void *, uint32_t, dstPointerArray> dstCharPointerArray;
typedef dstCastDynamicArray <float, int, uint32_t, dstIntArray> dstFloatArray;
typedef dstCastDynamicArray <double, int64_t, uint32_t, dstInt64Array> dstDoubleArray;

// Dynamic array types for int, int64_t, void * char *, with a size storage size
// of 16 bits (max 32768 entries).
typedef dstDynamicArray <int, uint16_t> dstSmallIntArray;
typedef dstDynamicArray <int64_t, uint16_t> dstSmallInt64Array;<commit_msg>Fix casting bug in dstCastDynamicArray class<commit_after>/*

Copyright (c) 2014 <NAME> <<EMAIL>>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

*/

#ifndef __DST_DYNAMIC_ARRAY_H__
#define __DST_DYNAMIC_ARRAY_H__

#include <dstConfig.h>
#include <dstRandom.h>

#include <stdio.h>
#include <signal.h>

// Dynamic array template class allows any type of data.
// T is the type of the stored data.
// S is the integer type for the size of the array (normally int, allowing for
// 2G (2^31) entries, but for small arrays unsigned short/uint16_t (max 32768 entries)
// or especially unsigned char (max 128 entries) can save a little space, especially when
// lots of very small arrays are expected.

template <class T, class S>
class DST_API dstDynamicArrayBaseClass {
private :
	T *data;
	S nu_elements;
	S max_elements;

	// By how much to expand the array.
	virtual inline S GetExpansionHint(S capacity) const = 0;
	// The absolute maximum capacity allowed by the class variant.
        inline void ResizeCapacity(S new_capacity) {
                max_elements = new_capacity;
		data = (T *)realloc(data, sizeof(T) * max_elements);
	}
	inline void ExpandCapacity() {
		S new_capacity = GetExpansionHint(max_elements);
		if (new_capacity < max_elements) {
			// When new_capacity is less than max_elements, usually zero,
			// the maximum capacity has been reached, so the element cannot be
			// added. Exit with an error message.
			fprintf(stderr, "dstDynamicArray: maximum array capacity overflow\n");
			raise(SIGABRT);
		}
		ResizeCapacity(new_capacity);
        }

public :
	virtual inline S MaxCapacity() const = 0;
	dstDynamicArrayBaseClass() {
		nu_elements = 0;
		max_elements = 0;
		data = NULL;
	}
	dstDynamicArrayBaseClass(S starting_capacity) {
		nu_elements = 0;
		data = NULL;
		ResizeCapacity(starting_capacity);
	}
        // There is no deconstuctor. Run FreeData() or MakeEmpty() to free storage space.
	inline void FreeData() const {
		free(data);
        }
	inline void MakeEmpty() {
		FreeData();
		nu_elements = 0;
		max_elements = 0;
		data = NULL;	
	}
	inline S Size() const {
		return nu_elements;
	}
	inline S AllocatedSize() const {
		return max_elements;
        }
	// Get value of element i.
	inline T Get(S i) const {
		return data[i];
	}
        // Set value of element i.
        inline void Set(S i, T v) {
		data[i] = v;
        }
	// Get a pointer to the start of the array.
	inline T *DataPointer() const {
                return data;
        }
	// Get a pointer to a specific element.
        inline T *DataPointer(S i) const {
		return &data[i];
        }
        // Trim capacity to the number of elements. This may result in a unusual
	// (e.g. non-power of two) capacity.
	inline void TrimCapacity() {
		ResizeCapacity(nu_elements);
	}
	// Set the maximum capacity to a specific size.
        inline void SetCapacity(S capacity) {
		ResizeCapacity(capacity);
	}
        // Truncate array to n elements. Capacity remains the same. n must be less or equal
	// to the current number of elements as reported by Size().
	inline void Truncate(S n) {
		nu_elements = n;
        }
	// Add element with value V.
	inline void Add(T v) {
		if (nu_elements == max_elements)
			ExpandCapacity();
		data[nu_elements] = v;
		nu_elements++;
	}
};

// Standard implementation of the class, which doubles the capacity each time
// the array is full. T is the type of the stored data, S the index storage type.

template <class T, class S>
class DST_API dstDynamicArray : public dstDynamicArrayBaseClass <T, S> {
public :
	dstDynamicArray(S starting_capacity = 4) { }
	// The absolute maximum capacity allowed by the class variant.
	inline S MaxCapacity() const {
		return (S)1 << (sizeof(S) * 8 - 1);
	}

private :
	// By how much to expand the array.
	inline S GetExpansionHint(S size) const {
		// Expand the size to the next power of two.
                uint32_t log2_size = dstCalculateLog2(size);
		return (S)((S)1 << (log2_size + 1));
	}
};

// Template class to cast DynamicArray class type to another, same-sized type.
// U is the new type, T is the same-sized type for which an existing class exists,
// S is the integer type for the size storage (usually uint32_t), and C2 is the name
// of the existing class.

template <class U, class T, class S, class C2>
class DST_API dstCastDynamicArray : public C2 {
public :
	dstCastDynamicArray(S starting_capacity = 4) { }
	// Get value of element i.
	inline U Get(S i) const {
		return (U)(((C2 *)this)->Get(i));
	}
        // Set value of element i.
        inline void Set(S i, U v) const {
		((C2 *)this)->Set(i, (T)v);
        }
	// Get a pointer to the start of the array.
	inline U *DataPointer() const {
                return (U *)((C2 *)this)->DataPointer();
        }
	// Get a pointer to a specific element.
        inline U *DataPointer(uint32_t i) const {
		return &(U *)((C2 *)this)->DataPointer(i);
        }
	inline void Add(U s) {
		((C2 *)this)->Add((T)s);
	}
};

// Dynamic array types for int, int64_t, void * char *, with a size storage size
// of 32 bits (max 2G entries).
typedef dstDynamicArray <int, uint32_t> dstIntArray;
typedef dstDynamicArray <int64_t, uint32_t> dstInt64Array;
#if UINTPTR_MAX == 0xFFFFFFFF
// 32-bit pointers.
typedef dstCastDynamicArray <void *, int, uint32_t, dstIntArray> dstPointerArray;
#else
// 64-bit pointers
typedef dstCastDynamicArray <void *, int64_t, uint32_t, dstInt64Array> dstPointerArray;
#endif
typedef dstCastDynamicArray <char *, void *, uint32_t, dstPointerArray> dstCharPointerArray;
typedef dstCastDynamicArray <float, int, uint32_t, dstIntArray> dstFloatArray;
typedef dstCastDynamicArray <double, int64_t, uint32_t, dstInt64Array> dstDoubleArray;

// Dynamic array types for int, int64_t, void * char *, with a size storage size
// of 16 bits (max 32768 entries).
typedef dstDynamicArray <int, uint16_t> dstSmallIntArray;
typedef dstDynamicArray <int64_t, uint16_t> dstSmallInt64Array;
{'fraction_non_alphanumeric': 0.09341793440868436, 'fraction_numerical': 0.015595137986392478, 'mean_word_length': 3.4405974202308216, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '2923572', 'n_tokens_mistral': 4311, 'n_tokens_neox': 3984, 'n_words': 1605}