/* This file is part of cqual.
   Copyright (C) 2003 The Regents of the University of California.

cqual is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

cqual is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with cqual; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

#ifndef TYPED_MAP_H
#define TYPED_MAP_H

#include "hash.h"
#include <regions.h>
#include "bool.h"
#include "stdint.h"

#if 0
#define DECLARE_MAP(name,domain_type,range_type) \
static inline name make_ ## name(region r, unsigned long size); \
static inline void name ## _reset(name m); \
static inline unsigned long name ## _size(name m); \
static inline bool name ## _lookup(name m, domain_type k, range_type *d); \
static inline bool name ## _insert(name m, domain_type k, range_type d); \
static inline bool name ## _remove(name m, domain_type k); \
static inline name name ## _copy(region r, name m); \
static inline name name ## _map(region r, name m, \
                                range_type (*f)(domain_type, range_type, void *), \
                                void *arg); \
static inline void name ## _scan(name m, name ## _scanner *ms); \
static inline bool name ## _next(name ## _scanner *ms, \
                                 domain_type *k, range_type *d); \
static inline void name ## _scan_sorted(name m, int (*f)(domain_type, domain_type), \
                                        name ## _scanner_sorted *mss); \
static inline bool name ## _next_sorted(name ## _scanner_sorted *ms, domain_type *k, \
                                        range_type *d);
#endif

#define DEFINE_MAP(name,domain_type,range_type,hash_func,keyeq_func) \
typedef struct { hash_table ht; } *name; \
typedef struct { hash_table_scanner hts; } name ## _scanner; \
typedef struct { hash_table_scanner_sorted htss; } name ## _scanner_sorted; \
static inline name make_ ## name(region r, unsigned long size) { return (name) make_hash_table(r, size, (hash_fn) hash_func, (keyeq_fn) keyeq_func); } \
static inline void name ## _reset(name m) { hash_table_reset((hash_table) m); } \
static inline unsigned long name ## _size(name m) { return hash_table_size((hash_table) m); } \
static inline bool name ## _lookup(name m, domain_type k, range_type *d) { return hash_table_lookup((hash_table) m, (hash_key) k, (hash_data *) d); } \
static inline bool name ## _insert(name m, domain_type k, range_type d) { return hash_table_insert((hash_table) m, (hash_key) k, (hash_data) (intptr_t) d); } \
static inline bool name ## _remove(name m, domain_type k) { return hash_table_remove((hash_table) m, (hash_key) k); } \
static inline name name ## _copy(region r, name m) { return (name) hash_table_copy(r, (hash_table) m); } \
static inline name name ## _map(region r, name m, range_type (*f)(domain_type, range_type, void *), void *arg) { return (name) hash_table_map(r, (hash_table) m, (hash_map_fn) f, arg); } \
static inline void name ## _scan(name m, name ## _scanner *ms) { hash_table_scan((hash_table) m, &ms->hts); } \
static inline bool name ## _next(name ## _scanner *ms, domain_type *k, range_type *d) { return hash_table_next(&ms->hts, (hash_key *) k, (hash_data *) d); } \
static inline void name ## _scan_sorted(name m, int (*f)(domain_type, domain_type), name ## _scanner_sorted *mss) { hash_table_scan_sorted((hash_table) m, (keycmp_fn) f, &mss->htss); } \
static inline bool name ## _next_sorted(name ## _scanner_sorted *ms, domain_type *k, range_type *d) { return hash_table_next_sorted(&ms->htss, (hash_key *) k, (hash_data *) d); }

#endif
