[ create a new paste ] login | about

Link: http://codepad.org/ZkgNyw4Q    [ raw code | output | fork ]

AaronMiller - C++, pasted on May 22:
//
// Dictionary<T> Class from MkSDK
// Public Domain
//

#ifndef MKSDK_DICTIONARY_H
#define MKSDK_DICTIONARY_H

//#include "Config.h"
#ifndef MKSDK_CONFIG_H
#define MKSDK_CONFIG_H
#include <cassert>

//quick replacement for above header's MK_ASSERT() macro
#define MK_ASSERT assert

namespace mk {

//quick replacement for above header's types
typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int   u32;
typedef   signed char  i8;
typedef   signed short i16;
typedef   signed int   i32;

}
#endif

namespace mk {

template<typename T> class Dictionary;

}

template<typename T> class mk::Dictionary {
public:
	struct Entry {
	friend class mk::Dictionary<T>;
	public:
		T *p;
		Entry *entries;

		inline Entry(): p((T *)0), entries((Entry *)0) {}
		inline ~Entry() {
			delete [] entries; entries = (Entry *)0;
			//delete p; p = (T *)0;
		}
	};

	Dictionary(const char *allowed);
	~Dictionary();

	Entry *Find(const char *key);
	Entry *Lookup(const char *key);

protected:
	mk::u8 mConvmap[256];

	mk::u8 mNumEntries;
	Entry *mEntries;

	mk::u8 GenerateConvmap(const char *allowed);
	Entry *FindFromEntry(Entry *&entries, const char *str, bool create);
};

template<typename T>
mk::u8 mk::Dictionary<T>::GenerateConvmap(const char *allowed) {
	mk::u8 i, j, k;

	for(i=0; i<255; i++)
		mConvmap[i] = 0xFF;

	for(i=0; allowed[i] && i<255; i++) {
		k = ((mk::u8 *)allowed)[i];
		if (k >= 255)
			return 0;

		mConvmap[k] = i;
	}

	for(j=0; j<i; j++) {
		for(k=j + 1; k<i; k++) {
			if (allowed[j]==allowed[k])
				return 0; /*duplicate entries*/
		}
	}

	return i;
}

template<typename T>
typename mk::Dictionary<T>::Entry *mk::Dictionary<T>::FindFromEntry
(Entry *&entries, const char *str, bool create) {
	mk::u8 i;

	MK_ASSERT(mEntries != (Entry *)0);
	MK_ASSERT(entries != (Entry *)0);
	MK_ASSERT(str != (const char *)0);

	i = mConvmap[*(mk::u8 *)str++];
	if (i==0xFF)
		return (Entry *)0;

	if (*str) {
		if (!entries[i].entries) {
			if (create)
				entries[i].entries = new Entry[mNumEntries]();

			if (!entries[i].entries)
				return (Entry *)0;
		}

		return FindFromEntry(entries[i].entries, str, create);
	}

	return &entries[i];
}

template<typename T>
inline mk::Dictionary<T>::Dictionary(const char *allowed) {
	MK_ASSERT(allowed != (const char *)0);

	mNumEntries = GenerateConvmap(allowed);
	MK_ASSERT(mNumEntries != 0);

	mEntries = new Entry[mNumEntries]();
}
template<typename T>
inline mk::Dictionary<T>::~Dictionary() {
	delete [] mEntries; mEntries = (Entry *)0;
	mNumEntries = 0;
}

template<typename T>
inline typename mk::Dictionary<T>::Entry *mk::Dictionary<T>::Find
(const char *key) {
	return FindFromEntry(mEntries, key, false);
}
template<typename T>
inline typename mk::Dictionary<T>::Entry *mk::Dictionary<T>::Lookup
(const char *key) {
	return FindFromEntry(mEntries, key, true);
}

#endif

#include <cstdio>
#include <cstdlib>

typedef struct var_s {
  int x;
} var_t;
mk::Dictionary<var_t> gVars("abcdefghijklmnopqrstuvwxyz");

var_t *SetVar(const char *name, int x) {
  mk::Dictionary<var_t>::Entry *entry;

  entry = gVars.Lookup(name);
  if (!entry)
    return (var_t *)0;

  if (!entry->p)
    entry->p = new var_t();

  entry->p->x = x;
  return entry->p;
}
int GetVar(const char *name) {
  mk::Dictionary<var_t>::Entry *entry;

  entry = gVars.Find(name);
  if (!entry)
    return 0;

  if (!entry->p)
    return 0;

  return entry->p->x;
}

int main() {
  SetVar("car", 2);
  SetVar("cat", 4);
  SetVar("cow", 7);
  SetVar("cam", 8);

#define PrintVar(n) printf("%s=%i\n", (n), GetVar((n)))
  PrintVar("car");
  PrintVar("cat");
  PrintVar("cow");
  PrintVar("cam");
  PrintVar("nop");
  PrintVar("no?");
#undef PrintVar

  return EXIT_SUCCESS;
}


Output:
1
2
3
4
5
6
car=2
cat=4
cow=7
cam=8
nop=0
no?=0


Create a new paste based on this one


Comments: