<commit_before>/*
 * Copyright (c) 2005, <NAME> and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

#ifndef _ObjectList_H
#define _ObjectList_H

//---- standard-module include ----------------------------------------------
#include "ITOString.h"

//---- c-module include -----------------------------------------------------
#include <list>

//---- const ----------------------------------------------------------------
using namespace std;

class NullType {};

template <typename T>
class TypeTraits
{
private:
	template <class U> struct PointerTraits {
		enum { result = false };
		typedef NullType PointeeType;
	};

	template <class U> struct PointerTraits<U *> {
		enum { result = true };
		typedef U PointeeType;
	};

public:
	enum { isPointer = PointerTraits<T>::result };
	typedef typename PointerTraits<T>::PointeeType PointeeType;
};

template <int v>
struct Int2Type {
	enum { value = v };
};

template<typename Tp>
class ObjectList : public list<Tp>
{
	enum DeleteFuncSelector { Reftype, Pointertype };

	void DoDeleteObject(const typename list<Tp>::value_type &newObjPtr, Int2Type<Reftype> ) {};
	void DoDeleteObject(const typename list<Tp>::value_type &newObjPtr, Int2Type<Pointertype> ) {
		delete newObjPtr;
	};

public:
	ObjectList(const char *name, Allocator *a = Storage::Global())
		: fShutdown(false)
		, fDestructiveShutdown(false)
		, fName(name, -1, a)
		, fpAlloc(a)
	{}

	virtual ~ObjectList() {
		if ( fDestructiveShutdown ) {
			// no more workers waiting and capable of emptying the list
			// we have to delete elements if they were pointers, let an appropriate function do this work
			enum { delAlgo = (TypeTraits<Tp>::isPointer) ? Pointertype : Reftype };
			while ( IntGetSize() > 0 ) {
				Tp pElement;
				IntRemoveHead(pElement);
				DoDeleteObject(pElement, Int2Type<delAlgo>() );
			}
		}
	}

	virtual bool InsertTail(const typename list<Tp>::value_type &newObjPtr) {
		if ( !IsShuttingDown() ) {
			push_back(newObjPtr);
			return true;
		}
		return false;
	}

	/*! removes the head element of the list
		\param aElement reference to a receiving element, depending on the type (pointer, element) an assignment operator of the element is required!
		\param lSecs unused
		\param lNanosecs unused
		\return true only when an element could be get, false in case the list was empty or we are in shutdown mode */
	virtual bool RemoveHead(typename list<Tp>::reference aElement, long lSecs = 0L, long lNanosecs = 0L) {
		if ( !IsShuttingDown() && !this->empty() ) {
			IntRemoveHead(aElement);
			return true;
		}
		return false;
	}

	inline virtual size_t GetSize() {
		return IntGetSize();
	}

	/*! Method to be called to signal that we want to destroy the list. If the elements should still be consumed by the workers reading from the list false should be passed as argument. If a 'destructive' shutdown is wanted true should be passed.
		\param bDestructive set to true if the list should not be emptied by the workers and not accessed further */
	inline virtual void SignalShutdown(bool bDestructive = false) {
		fDestructiveShutdown = bDestructive;
		fShutdown = true;
	}

	inline virtual bool IsShuttingDown() const {
		return fShutdown;
	}

protected:
	virtual void IntRemoveHead(typename list<Tp>::reference aElement) {
		aElement = this->front();
		this->pop_front();
	}

	inline virtual size_t IntGetSize() const {
		return this->size();
	}

	bool			fShutdown;<commit_msg>based on Modern C++ Design, written by <NAME>, I added a delete method in case the list contains pointers to objects<commit_after>/*
 * Copyright (c) 2005, <NAME> and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

#ifndef _ObjectList_H
#define _ObjectList_H

//---- standard-module include ----------------------------------------------
#include "config_foundation.h"	// for definition of EXPORTDECL_FOUNDATION
#include "ITOString.h"
#include "Dbg.h"
#if defined(WIN32)
#include "TypeTraits.h"
#else
class NullType {};

namespace Loki
{
	template <int v>
	struct Int2Type {
		enum { value = v };
	};

	template <typename T>
	class TypeTraits
	{
	private:
		template <class U> struct PointerTraits {
			enum { result = false };
			typedef NullType PointeeType;
		};

		template <class U> struct PointerTraits<U *> {
			enum { result = true };
			typedef U PointeeType;
		};

	public:
		enum { isPointer = PointerTraits<T>::result };
	};
};
#endif

//---- c-module include -----------------------------------------------------
#include <list>

//---- class ObjectList ----------------------------------------------------------------

template<typename Tp>
class EXPORTDECL_FOUNDATION ObjectList : public std::list<Tp>
{
	// tricky section to determine if given type is a pointer and deletable
	// ideas from Alexandrescu, loki-lib
	enum DeleteFuncSelector { Reftype, Pointertype };

	void DoDeleteObject(const typename std::list<Tp>::value_type &newObjPtr, Loki::Int2Type<Reftype> ) {};
	void DoDeleteObject(const typename std::list<Tp>::value_type &newObjPtr, Loki::Int2Type<Pointertype> ) {
		delete newObjPtr;
	};

public:
	ObjectList(const char *name, Allocator *a = Storage::Global())
		: fShutdown(false)
		, fDestructiveShutdown(false)
		, fName(name, -1, a)
		, fpAlloc(a)
	{}

	virtual ~ObjectList() {
		StartTrace1(ObjectList.~ObjectList, (fDestructiveShutdown ? "destructive" : ""));
		if ( fDestructiveShutdown ) {
			// no more workers waiting and capable of emptying the list
			// we have to delete elements if they were pointers, let an appropriate function do this work
			enum { delAlgo = (Loki::TypeTraits<Tp>::isPointer) ? Pointertype : Reftype };
			while ( IntGetSize() > 0 ) {
				Tp pElement;
				IntRemoveHead(pElement);
				DoDeleteObject(pElement, Loki::Int2Type<delAlgo>() );
			}
		}
	}

	virtual bool InsertTail(const typename std::list<Tp>::value_type &newObjPtr) {
		StartTrace(ObjectList.InsertTail);
		if ( !IsShuttingDown() ) {
			push_back(newObjPtr);
			Trace("pushing object");
			return true;
		}
		Trace("in shutdown");
		return false;
	}

	/*! removes the head element of the list
		\param aElement reference to a receiving element, depending on the type (pointer, element) an assignment operator of the element is required!
		\param lSecs unused
		\param lNanosecs unused
		\return true only when an element could be get, false in case the list was empty or we are in shutdown mode */
	virtual bool RemoveHead(typename std::list<Tp>::reference aElement, long lSecs = 0L, long lNanosecs = 0L) {
		StartTrace(ObjectList.RemoveHead);
		if ( !IsShuttingDown() && !IntIsEmpty() ) {
			IntRemoveHead(aElement);
			Trace("element removed");
			return true;
		}
		Trace("in shutdown or empty list");
		return false;
	}

	inline virtual size_t GetSize() {
		return IntGetSize();
	}

	/*! Method to be called to signal that we want to destroy the list. If the elements should still be consumed by the workers reading from the list false should be passed as argument. If a 'destructive' shutdown is wanted true should be passed.
		\param bDestructive set to true if the list should not be emptied by the workers and not accessed further */
	inline virtual void SignalShutdown(bool bDestructive = false) {
		StartTrace1(ObjectList.SignalShutdown, (bDestructive ? "destructive" : ""));
		fDestructiveShutdown = bDestructive;
		fShutdown = true;
	}

	inline virtual bool IsShuttingDown() const {
		return fShutdown;
	}

	inline virtual void ResetAfterShutdown() {
		fShutdown = false;
		fDestructiveShutdown = false;
	}

protected:
	virtual void IntRemoveHead(typename std::list<Tp>::reference aElement) {
		aElement = this->front();
		this->pop_front();
	}

	inline virtual size_t IntGetSize() const {
		return this->size();
	}
	inline virtual bool IntIsEmpty() const {
		return this->empty();
	}

	bool			fShutdown;
{'fraction_non_alphanumeric': 0.13887875471239208, 'fraction_numerical': 0.003405083302930804, 'mean_word_length': 3.4286483575659665, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 53, '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': '2462836', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2432, 'n_words': 834}