<commit_before>#pragma once

#include <type_traits>

namespace cl {
namespace sycl {
namespace detail {

template <typename T>
struct ptr_or_val {
private:
	bool is_pointer;
	void* data;

	T* get_ptr() const {
		return reinterpret_cast<T*>(data);
	}

public:
	static_assert(sizeof(T) <= sizeof(void*), "Type T is too big to store as ptr_or_val");

	ptr_or_val(nullptr_t, T value)
		: is_pointer(false), data(*((void**)&value)) {}
	ptr_or_val()
		: ptr_or_val(nullptr, 0) {}
	ptr_or_val(T* ptr)
		: is_pointer(true), data(ptr) {}

	ptr_or_val& operator=(T n) {
		if(!is_pointer) {
			data = *((T**)&n);
		}
		else {
			*get_ptr() = n;
		}
		return *this;
	}

	operator T() const {
		if(!is_pointer) {
			return *((T*)&data);
		}
		else {
			return *get_ptr();
		}
	}
	operator T&() {
		if(!is_pointer) {
			return *((T*)&data);
		}
		else {
			return *get_ptr();
		}
	}

	ptr_or_val<T*> operator&() {
		return ptr_or_val<T*>(reinterpret_cast<T**>(&data));
	}
	ptr_or_val<typename std::remove_pointer<T>::type> operator*() {
		return ptr_or_val<typename std::remove_pointer<T>::type>(reinterpret_cast<T>(*data));
	}
};
<commit_msg>Split ptr_or_val in two templated implementations.<commit_after>#pragma once

#include <type_traits>

namespace cl {
namespace sycl {
namespace detail {

template <typename T, bool holds_pointer = false>
struct ptr_or_val;

template <typename T>
struct ptr_or_val<T, false> {
private:
	friend struct ptr_or_val<T, true>;
	T data;

public:
	ptr_or_val(T value = 0)
		: data(value) {}
	ptr_or_val(const ptr_or_val<T, true>& ptr)
		: data(*(ptr.data)) {}

	ptr_or_val& operator=(T n) {
		data = n;
		return *this;
	}

	operator T() const {
		return data;
	}
	operator T&() {
		return data;
	}

	ptr_or_val<T, true> operator&() {
		return ptr_or_val<T, true>(&data);
	}
	ptr_or_val<typename std::remove_pointer<T>::type, false> operator*() {
		return ptr_or_val<typename std::remove_pointer<T>::type, false>(*data);
	}
};


template <typename T>
struct ptr_or_val<T, true> {
private:
	friend struct ptr_or_val<T, false>;
	T* data;

public:
	ptr_or_val(T* ptr)
		: data(ptr) {}
	ptr_or_val(ptr_or_val<T, false>& value)
		: data(&(value.data)) {}

	ptr_or_val& operator=(T n) {
		*data = n;
		return *this;
	}

	operator T() const {
		return *data;
	}
	operator T&() {
		return *data;
	}

	ptr_or_val<T*, true> operator&() {
		return ptr_or_val<T*, true>(&data);
	}
	ptr_or_val<typename std::remove_pointer<T>::type, false> operator*() {
		return ptr_or_val<typename std::remove_pointer<T>::type, false>(*data);
	}
};

{'fraction_non_alphanumeric': 0.17040535222353403, 'fraction_numerical': 0.0007870916961826052, 'mean_word_length': 4.623893805309734, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 36, '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': '7133423', 'n_tokens_mistral': 1090, 'n_tokens_neox': 1028, 'n_words': 214}