//
// 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;
}