// -*-c++-*- /* $Id: keyfunc.h,v 1.5 2001/07/18 03:02:17 dm Exp $ */ /* * * Copyright (C) 1998 David Mazieres (dm@uun.org) * * 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 2, 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #ifndef _KEYFUNC_H_ #define _KEYFUNC_H_ 1 template struct unref_t { typedef T base_type; typedef T unref_type; typedef const T &ref_type; typedef T &ncref_type; }; template struct unref_t { typedef T base_type; typedef const T unref_type; typedef const T &ref_type; typedef T &ncref_type; }; template struct unref_t { typedef T base_type; typedef T unref_type; typedef const T &ref_type; typedef T &ncref_type; }; template struct unref_t { typedef T base_type; typedef const T unref_type; typedef const T &ref_type; typedef T &ncref_type; }; #define CREF(T) unref_t::ref_type #define UNREF(T) unref_t::unref_type #define UNCREF(T) unref_t::base_type #define NCREF(T) unref_t::ncref_type #define HASHSEED 5381 inline u_int hash_bytes (const void *_key, int len, u_int seed = HASHSEED) { const u_char *key = (const u_char *) _key; const u_char *end; for (end = key + len; key < end; key++) seed = ((seed << 5) + seed) ^ *key; return seed; } inline u_int hash_string (const void *_p, u_int v = HASHSEED) { const char *p = (const char *) _p; while (*p) v = (33 * v) ^ (unsigned char) *p++; return v; } inline u_int hash_rotate (u_int val, u_int rot) { rot %= 8 * sizeof (val); return (val << rot) | (val >> (8 * sizeof (val) - rot)); } class hash_t { u_int val; public: hash_t () {} hash_t (u_int v) : val (v) {} operator u_int() const { return val; } }; template struct compare { compare () {} int operator() (CREF (T) a, CREF (T) b) const { return a < b ? -1 : b < a; } }; template struct compare : compare { compare () {} }; template struct equals { equals () {} bool operator() (CREF (T) a, CREF (T) b) const { return a == b; } }; template struct equals : equals { equals () {} }; template struct hashfn { hashfn () {} hash_t operator() (CREF (T) a) const { return a; } }; template struct hashfn : hashfn { hashfn () {} }; template struct hash2fn { hashfn h1; hashfn h2; hash2fn () {} hash_t operator() (CREF (T1) t1, CREF (T2) t2) const { return h1 (t1) ^ h2 (t2); } }; /* Don't compare pointers by accident */ template struct compare; template struct hashfn; /* Specializations for (char *) */ #define _CHAR_PTR(T, u) \ template<> \ struct compare { \ compare () {} \ int operator() (const u char *a, const u char *b) const \ { return strcmp ((char *) a, (char *) b); } \ }; \ template<> \ struct equals { \ equals () {} \ bool operator() (const u char *a, const u char *b) const \ { return !strcmp ((char *) a, (char *) b); } \ }; \ template<> \ struct hashfn { \ hashfn () {} \ hash_t operator() (const u char *a) const \ { return hash_string (a); } \ }; #define CHAR_PTR(T, u) _CHAR_PTR(T, u) _CHAR_PTR(T const, u) CHAR_PTR(char *,) CHAR_PTR(const char *,) CHAR_PTR(signed char *, signed) CHAR_PTR(const signed char *, signed) CHAR_PTR(unsigned char *, unsigned) CHAR_PTR(const unsigned char *, unsigned) template class keyfunc_1 { public: const F kf; keyfunc_1 () {} keyfunc_1 (const F &f) : kf (f) {} R operator() (CREF (V) a) const { return kf (a.*key); } }; template class keyfunc_2 { public: const F kf; keyfunc_2 () {} keyfunc_2 (const F &f) : kf (f) {} R operator() (CREF (V) a, CREF (V) b) const { return kf (a.*key, b.*key); } }; #endif /* !KEYFUNC_H_ */