//
// tardy - a tar post-processor
// Copyright (C) 1998, 1999, 2002, 2008, 2009, 2011 Peter Miller
//
// This program 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 3 of the License, or (at
// your option) any later version.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
//

#ifndef LIBTARDY_SYMTAB_H
#define LIBTARDY_SYMTAB_H

#include <libtardy/rcstring.h>

class symtab
{
public:
        ~symtab();
        symtab();

        void *query(const rcstring &) const;
        rcstring query_fuzzy(const rcstring &) const;
        void assign(const rcstring &, void *);
        void assign_push(const rcstring &, void *);
        void remove(const rcstring &);
        void dump(const char *) const;
        void walk(void (*func)(const symtab &st, const rcstring &key,
                void *data, void *arg), void *arg);
        void reap_set(void (*)(void *));

private:
        symtab(const symtab &);
        symtab &operator = (const symtab &);
        void split(void);

        struct row
        {
                rcstring        key;
                void    *data;
                row     *overflow;
        };

        symtab  *chain;
        void            (*reap)(void *);
        row     **hash_table;
        str_hash_ty     hash_modulus;
        str_hash_ty     hash_load;
};

#if 0

template <T>
class symbol_table<T>:
        private symtab
{
public:
        ~symbol_table<T>() {}
        symbol_table<T> : symtab() { reap_set(reaper); }

        void assign(const rcstring &key, const T &value)
                { symtab::assign(key, new T(arg)); }
        void remove(const rcstring &key)
                { symtab::remove(key); }
        bool contains(const rcstring &key) { return !!symtab::query(key); }
        T *query(const rcstring &key) { return (T *)symtab::query(key); }
        T &operator[](const rcstring &key) { void *tp = query(key);
                if (!tp) { tp = new T(); symtab::assign(key, tp); }
                return *tp; }

private:
        symbol_table<T>(const symbol_table<T> &) { }
        symbol_table<T> &operator = (const symbol_table<T> &) { return *this; }
        static void reaper(void *p) { delete (T *)p; }
};

#endif

#endif // LIBTARDY_SYMTAB_H
