Click here to Skip to main content
15,895,084 members
Articles / Desktop Programming / Win32

True Natural Language Understanding through a Conceptual Language Understanding Engine

Rate me:
Please Sign up or sign in to vote.
4.97/5 (55 votes)
11 Jan 201029 min read 68K   3.1K   118  
An article introducing an Artificial Intelligence technique that understands and manipulates concepts from text.
/*
The usage of this source code file, including but not limited to the reading, the compilation and 
redistribution, is subject to the license agreement detailed in the license.txt and license.pdf files
which accompany this source code. By proceeding to use this file you are acknowledging that you have
read either license.txt or license.pdf, and that you agree to be bound by the terms and conditions of
the license. If license.txt and license.pdf are not available, you are not licensed this file and you 
must delete it permanently; or contact the author at proy@conceptualspeech.com to obtain a copy of 
the license before proceeding to use this file.

Copyright Philippe Roy 2010 - proy@conceptualspeech.com.
*/

#ifndef __shared_auto_ptr_H__
#define __shared_auto_ptr_H__

#include <map>

/* This file exposes 1 public usable template class:

- shared_auto_ptr:

	Use a shared_auto_ptr in order to keep track of a resource and automatically invoke a delete on the
	destruction of the last referant.

	To call it, use the following syntax:

		shared_auto_ptr<T> var(T* ptr);

	or:

		shared_auto_ptr<T> var

	The template has destructor, copy constructor and assignment logic to keep track of the referants.

	In order to later extract the kept resource, use the following call:

		T* var.get()

	or simply use the deferencing operator (overloaded to return T*):

		T * var->

	For individual method documentation, refer to the template definition lower.

*/

#pragma warning( disable : 4290 )

template <class T> class shared_auto_ptr;

using namespace std;

#include "DebugDefinitions.h"

/* *************************** interfaces ************************** */

// - contained_auto_ptr:

// The contained_auto_ptr is the container of a unique ptr that holds a count
// of the referants.

// It hides the copy constructor and assignment operator in its private section
// in order to ensure that it is never constructed or assigned to another object
// without going through the shared_auto_ptr.

// There are no public method in this class since it is expected to exclusively be 
// called by its friend class shared_auto_ptr<T>.

template <class T> class contained_auto_ptr
{

public:
	friend class shared_auto_ptr<T>;

protected:

	// The GetContainer acts as a static constructor, but constructs only if no
	// other contained_auto_ptr<T> points to the same pointer p.
	static contained_auto_ptr<T> *GetContainer(T* p = NULL) throw();

	// In order to extract the value pointed by the object, use the get() method.
	T *get() const throw();

	// Destructor...
	~contained_auto_ptr() throw();

private:

	// Constructor: never call directly. Use GetContainer instead...
	contained_auto_ptr(T* p = NULL) throw();

	// This static map holds the equivalence between pointers and contained_auto_ptr objects
	// already created.
	static map<uintptr_t, contained_auto_ptr<T>*> m_equivalenceMap;

	// We hide the copy constructor and the assignment operators to ensure they
	// are never used.
	contained_auto_ptr(const contained_auto_ptr&) throw();
	void operator=(const contained_auto_ptr&) throw();

	int m_count;	// holds the count of the referants.
	T *_ptr;		// T* being held by the object.
};

// - shared_auto_ptr (*** PUBLIC INTERFACE ***):

// The shared_auto_ptr allows for the creation of a referant to a location in memory. It may create a
// contained_auto_ptr object in the event that it is the first referant of the memory location. Upon the
// destruction of the last referant, the memory allocated will be deleted.

template <class T> class shared_auto_ptr
{

public:

	// Constructor:

	// REQUIREMENTS:
	// - p must point to the memory location to track.
	// PROMISES:
	// - upon destruction of the shared_auto_ptr object, p will be deleted only
	// when the last referant will have been deleted.

	shared_auto_ptr(T* p = NULL) throw();

	// Destructor:

	// REQUIREMENTS:
	// - none.
	// PROMISES:
	// - upon destruction of the shared_auto_ptr object, the pointer provided upon construction
	// or obtained through the assignment operator will be deleted only 
	// when the last referant will have been deleted.

	~shared_auto_ptr() throw();

	// Copy constructor:

	// REQUIREMENTS:
	// - none.
	// PROMISES:
	// - upon destruction of the shared_auto_ptr object, the pointer provided upon construction
	// or obtained through the assignment operator will be deleted only 
	// when the last referant will have been deleted.

	shared_auto_ptr(const shared_auto_ptr&) throw();

	// assignment operator:

	// REQUIREMENTS:
	// - none.
	// PROMISES:
	// - upon destruction of the shared_auto_ptr object, the pointer provided upon construction
	// or obtained through the assignment operator will be deleted only 
	// when the last referant will have been deleted.

	void operator=(const shared_auto_ptr&) throw();

	// get():

	// REQUIREMENTS:
	// - Do not use the returned pointer outside the scope where it was obtained (as when that
	// scope is left, the shared_auto_ptr object may be deleted, and the memory associated with
	// it also consequently).
	// PROMISES:
	// - Within the same scope, the returned pointer will be good.

	T *get() const throw();

	// -> operator:

	// REQUIREMENTS:
	// - Do not use the returned pointer outside the scope where it was obtained (as when that
	// scope is left, the shared_auto_ptr object may be deleted, and the memory associated with
	// it also consequently).
	// PROMISES:
	// - Within the same scope, the returned pointer will be good.

	T *operator->() const throw() { return get(); }

private:
	contained_auto_ptr<T> *m_contained_auto_ptr;
};

/* ******************** shared_auto_ptr support ******************** */

template <class T> map<uintptr_t, contained_auto_ptr<T>*> contained_auto_ptr<T>::m_equivalenceMap;

template <class T> contained_auto_ptr<T> *contained_auto_ptr<T>::GetContainer(T* p) throw()
{
	if ((p != NULL) && (contained_auto_ptr<T>::m_equivalenceMap.find((uintptr_t)p) != contained_auto_ptr<T>::m_equivalenceMap.end()))
	{
		return contained_auto_ptr<T>::m_equivalenceMap[(uintptr_t)p];
	}
	else
	{
		return new contained_auto_ptr<T>(p);
	}
}

template <class T> contained_auto_ptr<T>::contained_auto_ptr(T* p) throw(): _ptr(p), m_count(0)
{
	if (p)
	{
		contained_auto_ptr<T>::m_equivalenceMap[(uintptr_t)p] = this;
	}
}

template <class T> contained_auto_ptr<T>::~contained_auto_ptr() throw()
{ 
	contained_auto_ptr<T>::m_equivalenceMap.erase((uintptr_t)_ptr);
	delete _ptr;
}

template <class T> T *contained_auto_ptr<T>::get() const throw() 
{ 
	return _ptr; 
}

template <class T> shared_auto_ptr<T>::shared_auto_ptr(T* p) throw(): m_contained_auto_ptr(NULL)
{
	m_contained_auto_ptr = contained_auto_ptr<T>::GetContainer(p);
	m_contained_auto_ptr->m_count++;
}

template <class T> shared_auto_ptr<T>::~shared_auto_ptr() throw()
{
	m_contained_auto_ptr->m_count--;
	if (!m_contained_auto_ptr->m_count)
	{
		delete m_contained_auto_ptr;
	}
}

template <class T> shared_auto_ptr<T>::shared_auto_ptr(const shared_auto_ptr& copy) throw()
{
	copy.m_contained_auto_ptr->m_count++;
	m_contained_auto_ptr = copy.m_contained_auto_ptr;
}

template <class T> void shared_auto_ptr<T>::operator=(const shared_auto_ptr& copy) throw()
{
	if (copy.m_contained_auto_ptr != m_contained_auto_ptr)
	{
		contained_auto_ptr<T> *orig = m_contained_auto_ptr;
		m_contained_auto_ptr = copy.m_contained_auto_ptr;
		m_contained_auto_ptr->m_count++;
		orig->m_count--;
		if (!orig->m_count)
		{
			delete orig;
		}
	}
	else
	{
		m_contained_auto_ptr->m_count++;
	}
}

template <class T> T *shared_auto_ptr<T>::get() const throw() 
{ 
	if (m_contained_auto_ptr != NULL)
	{
		return m_contained_auto_ptr->get(); 
	}
	else
	{
		return NULL;
	}
}

#pragma warning( default : 4290 )

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
Canada Canada
Philippe Roy was a key contributor throughout his 20+ years career with many high-profile companies such as Nuance Communications, IBM (ViaVoice and ProductManager), VoiceBox Technologies, just to name a few. He is creative and proficient in OO coding and design, knowledgeable about the intellectual-property world (he owns many patents), tri-lingual, and passionate about being part of a team that creates great solutions.

Oh yes, I almost forgot to mention, he has a special thing for speech recognition and natural language processing... The magic of first seeing a computer transform something as chaotic as sound and natural language into intelligible and useful output has never left him.

Comments and Discussions