⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ptable.h

📁 早期freebsd实现
💻 H
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include <assert.h>#include <string.h>#ifdef TRADITIONAL_CPP#define name2(a,b) a/**/b#else /* not TRADITIONAL_CPP */#define name2(a,b) name2x(a,b)#define name2x(a,b) a ## b#endif /* not TRADITIONAL_CPP */#define PTABLE(T) name2(T,_ptable)#define PASSOC(T) name2(T,_passoc)#define PTABLE_ITERATOR(T) name2(T,_ptable_iterator)extern unsigned next_ptable_size(unsigned);extern unsigned long hash_string(const char *);#define declare_ptable(T)						      \									      \struct PASSOC(T) {							      \  char *key;							      	      \  T *val;								      \  PASSOC(T)();								      \};									      \									      \struct PTABLE(T);							      \									      \class PTABLE_ITERATOR(T) {						      \  PTABLE(T) *p;								      \  unsigned i;								      \public:									      \  PTABLE_ITERATOR(T)(PTABLE(T) *);					      \  int next(const char **, T **);					      \};									      \									      \class PTABLE(T) {							      \  PASSOC(T) *v;								      \  unsigned size;							      \  unsigned used;							      \  enum { FULL_NUM = 2, FULL_DEN = 3, INITIAL_SIZE = 17 };		      \public:									      \  PTABLE(T)();								      \  ~PTABLE(T)();								      \  void define(const char *, T *);					      \  T *lookup(const char *);						      \  friend class PTABLE_ITERATOR(T);					      \};#define implement_ptable(T)						      \									      \PASSOC(T)::PASSOC(T)()							      \: key(0), val(0)							      \{									      \}									      \									      \PTABLE(T)::PTABLE(T)()							      \{									      \  v = new PASSOC(T)[size = INITIAL_SIZE];				      \  used = 0;								      \}									      \									      \PTABLE(T)::~PTABLE(T)()							      \{									      \  for (unsigned i = 0; i < size; i++) {					      \    a_delete v[i].key;							      \    delete v[i].val;							      \  }									      \  a_delete v;								      \}									      \									      \void PTABLE(T)::define(const char *key, T *val)				      \{									      \  assert(key != 0);							      \  unsigned long h = hash_string(key);					      \  for (unsigned n = unsigned(h % size);					      \       v[n].key != 0;							      \       n = (n == 0 ? size - 1 : n - 1))					      \    if (strcmp(v[n].key, key) == 0) {					      \      delete v[n].val;							      \      v[n].val = val;							      \      return;								      \    }									      \  if (val == 0)								      \    return;								      \  if (used*FULL_DEN >= size*FULL_NUM) {					      \    PASSOC(T) *oldv = v;						      \    unsigned old_size = size;						      \    size = next_ptable_size(size);					      \    v = new PASSOC(T)[size];						      \    for (unsigned i = 0; i < old_size; i++)				      \      if (oldv[i].key != 0) {						      \	if (oldv[i].val == 0)						      \	  a_delete oldv[i].key;						      \	else {								      \	  for (unsigned j = unsigned(hash_string(oldv[i].key) % size);	      \	       v[j].key != 0;						      \	       j = (j == 0 ? size - 1 : j - 1))				      \		 ;							      \	  v[j].key = oldv[i].key;					      \	  v[j].val = oldv[i].val;					      \	}								      \      }									      \    for (n = unsigned(h % size);					      \	 v[n].key != 0;							      \	 n = (n == 0 ? size - 1 : n - 1))				      \      ;									      \    a_delete oldv;							      \  }									      \  char *temp = new char[strlen(key)+1];					      \  strcpy(temp, key);							      \  v[n].key = temp;							      \  v[n].val = val;							      \  used++;								      \}									      \									      \T *PTABLE(T)::lookup(const char *key)					      \{									      \  assert(key != 0);							      \  for (unsigned n = unsigned(hash_string(key) % size);			      \       v[n].key != 0;							      \       n = (n == 0 ? size - 1 : n - 1))					      \    if (strcmp(v[n].key, key) == 0)					      \      return v[n].val;							      \  return 0;								      \}									      \									      \PTABLE_ITERATOR(T)::PTABLE_ITERATOR(T)(PTABLE(T) *t)			      \: p(t), i(0)								      \{									      \}									      \									      \int PTABLE_ITERATOR(T)::next(const char **keyp, T **valp)		      \{									      \  unsigned size = p->size;						      \  PASSOC(T) *v = p->v;							      \  for (; i < size; i++)							      \    if (v[i].key != 0) {						      \      *keyp = v[i].key;							      \      *valp = v[i].val;							      \      i++;								      \      return 1;								      \    }									      \  return 0;								      \}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -