summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/lib/util/tagmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/lib/util/tagmap.h')
-rw-r--r--trunk/src/lib/util/tagmap.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/trunk/src/lib/util/tagmap.h b/trunk/src/lib/util/tagmap.h
new file mode 100644
index 00000000000..96430157ec3
--- /dev/null
+++ b/trunk/src/lib/util/tagmap.h
@@ -0,0 +1,224 @@
+/***************************************************************************
+
+ tagmap.h
+
+ Simple tag->object mapping functions.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __TAGMAP_H__
+#define __TAGMAP_H__
+
+#include "osdcore.h"
+
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define TAGMAP_HASH_SIZE 97
+
+
+enum _tagmap_error
+{
+ TMERR_NONE,
+ TMERR_OUT_OF_MEMORY,
+ TMERR_DUPLICATE
+};
+typedef enum _tagmap_error tagmap_error;
+
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* an entry in a tagmap */
+typedef struct _tagmap_entry tagmap_entry;
+struct _tagmap_entry
+{
+ tagmap_entry * next;
+ void * object;
+ UINT32 fullhash;
+ char tag[1];
+};
+
+
+/* base tagmap structure */
+typedef struct _tagmap tagmap;
+struct _tagmap
+{
+ tagmap_entry * table[TAGMAP_HASH_SIZE];
+};
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+
+/* ----- map allocation and management ----- */
+
+/* allocate a new tagmap */
+tagmap *tagmap_alloc(void);
+
+/* free a tagmap, and all entries within it */
+void tagmap_free(tagmap *map);
+
+/* reset a tagmap by freeing all entries */
+void tagmap_reset(tagmap *map);
+
+
+
+/* ----- object management ----- */
+
+/* add a new entry to a tagmap */
+tagmap_error tagmap_add(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate);
+
+/* add a new entry to a tagmap, ensuring it has a unique hash value */
+tagmap_error tagmap_add_unique_hash(tagmap *map, const char *tag, void *object, UINT8 replace_if_duplicate);
+
+/* remove an entry from a tagmap */
+void tagmap_remove(tagmap *map, const char *tag);
+
+/* remove an entry from a tagmap by object pointer */
+void tagmap_remove_object(tagmap *map, void *object);
+
+
+
+/***************************************************************************
+ C++ WRAPPERS
+***************************************************************************/
+
+#ifdef __cplusplus
+
+/* derived class for C++ */
+template<class _ElementType> class tagmap_t : public tagmap
+{
+private:
+ tagmap_t(const tagmap &);
+ tagmap_t &operator=(const tagmap &);
+
+public:
+ tagmap_t() { memset(table, 0, sizeof(table)); }
+ ~tagmap_t() { reset(); }
+
+ void reset() { tagmap_reset(this); }
+
+ tagmap_error add(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return tagmap_add(this, tag, (void *)object, replace_if_duplicate); }
+ tagmap_error add_unique_hash(const char *tag, _ElementType object, bool replace_if_duplicate = false) { return tagmap_add_unique_hash(this, tag, (void *)object, replace_if_duplicate); }
+ void remove(const char *tag) { tagmap_remove(this, tag); }
+ void remove(_ElementType object) { tagmap_remove_object(this, object); }
+
+ _ElementType find(const char *tag) const { return reinterpret_cast<_ElementType>(tagmap_find(this, tag)); }
+ _ElementType find(const char *tag, UINT32 hash) const { return reinterpret_cast<_ElementType>(tagmap_find_prehashed(this, tag, hash)); }
+ _ElementType find_hash_only(const char *tag) const { return reinterpret_cast<_ElementType>(tagmap_find_hash_only(this, tag)); }
+};
+
+#endif
+
+
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ tagmap_hash - compute the hash of a tag
+-------------------------------------------------*/
+
+INLINE UINT32 tagmap_hash(const char *string)
+{
+ UINT32 hash = *string++;
+ char c;
+
+ while ((c = *string++) != 0)
+ hash = ((hash << 5) | (hash >> 27)) + c;
+
+ return hash;
+}
+
+
+/*-------------------------------------------------
+ tagmap_find_prehashed - find an object
+ associated with a tag, given the tag's
+ hash
+-------------------------------------------------*/
+
+INLINE void *tagmap_find_prehashed(const tagmap *map, const char *tag, UINT32 fullhash)
+{
+ tagmap_entry *entry;
+
+ for (entry = map->table[fullhash % ARRAY_LENGTH(map->table)]; entry != NULL; entry = entry->next)
+ if (entry->fullhash == fullhash && strcmp(entry->tag, tag) == 0)
+ return entry->object;
+ return NULL;
+}
+
+
+/*-------------------------------------------------
+ tagmap_find - find an object associated
+ with a tag
+-------------------------------------------------*/
+
+INLINE void *tagmap_find(const tagmap *map, const char *tag)
+{
+ return tagmap_find_prehashed(map, tag, tagmap_hash(tag));
+}
+
+
+/*-------------------------------------------------
+ tagmap_find_hash_only - find an object
+ associated with a tag using only the hash;
+ this generally works well but may occasionally
+ return a false positive
+-------------------------------------------------*/
+
+INLINE void *tagmap_find_hash_only(const tagmap *map, const char *tag)
+{
+ UINT32 fullhash = tagmap_hash(tag);
+ tagmap_entry *entry;
+
+ for (entry = map->table[fullhash % ARRAY_LENGTH(map->table)]; entry != NULL; entry = entry->next)
+ if (entry->fullhash == fullhash)
+ return entry->object;
+ return NULL;
+}
+
+
+#endif /* __TAGMAP_H__ */