// -*- C++ -*- // $RCSfile: groups.C,v $ // $Revision: 1.7 $ // $Author: langer $ // $Date: 2000/10/27 18:17:29 $ /* This software was produced by NIST, an agency of the U.S. government, * and by statute is not subject to copyright in the United States. * Recipients of this software assume all responsibilities associated * with its operation, modification and maintenance. However, to * facilitate maintenance we ask that before distributing modifed * versions of this software, you first contact the authors at * oof_manager@ctcms.nist.gov. */ #ifndef GROUPS_C #define GROUPS_C #include "groups.h" #include "goof.h" #include "menuDef.h" #include "ppm2oof.h" #include "stdlib.h" // have to define this elsewhere for each TYPE // Vec*> GroupMenu::menulist; // maybe not... template Vec*> GroupMenu::menulist; // ---------------------------------------------------- // template void Group::install() { for(int i=0; i::menulist.capacity(); i++) { GroupMenu::menulist[i]->AddCommand(name, GroupMenu::menulist[i]->grouphelp + " " + name, GroupMenu::menulist[i]->groupcmd); } } template void Group::uninstall() { for(int i=0; i::menulist.capacity(); i++) { GroupMenu::menulist[i]->RemoveOption(name); } } template Group &Group::operator=(const Group &g) { if(&g != this) { name = g.name; members = g.members; weeded = g.weeded; } return *this; } template void Group::clear_base() { members.resize(0); weeded = 1; } template void Group::clear() { clear_base(); } template int Group::compare(const void *a, const void *b) { TYPE *aa = (TYPE*) a; TYPE *bb = (TYPE*) b; if(*aa < *bb) return -1; if(*aa == *bb) return 0; return 1; } template void Group::weed() { if(weeded) return; weeded = 1; if(members.capacity() == 0) return; ::qsort(members, members.capacity(), sizeof(TYPE), compare); int nunique = 1; for(int i=1; i void Group::append_base(const Vec &list) { // add list of members to a group int oldsize = members.capacity(); members.resize(oldsize + list.capacity()); (void) memcpy(&members[oldsize], &list[0], list.capacity()*sizeof(TYPE)); weeded = 0; } template void Group::append_base(const TYPE &x) { weeded = 0; members.grow(1, x); } template void Group::append(const TYPE &x) { append_base(x); } template void Group::append(const Vec &x) { append_base(x); } template void Group::append(const Group &grp) { append(grp.members); } template void Group::remove_base(const TYPE &x) { members.remove(x); } template void Group::remove(const TYPE &x) { remove_base(x); } template void Group::remove_base(const Vec &c_rejects) { weed(); // sort and weed the group // sort the list of elements to be rejected Vec rejects(c_rejects); // non-const copy // don't want std::qsort ::qsort(rejects, rejects.capacity(), sizeof(TYPE), compare); // flag elements to be rejected Vec rejected(members.capacity(), 0); int g = 0; int r = 0; while(g < members.capacity() && r < rejects.capacity()) { if(r < rejects.capacity()-1 && rejects[r] == rejects[r+1]) // could be duplicates in reject list r++; else if(members[g] == rejects[r]) { rejected[g] = 1; g++; r++; } else if(members[g] < rejects[r]) g++; else r++; } members.remove_conditional(rejected); } template void Group::remove_base(const Group &grp) { remove_base(grp.members); } template void Group::remove(const Vec &x) { remove_base(x); } template void Group::remove(const Group &grp) { remove_base(grp); } template void Group::replace(const TYPE &obsolete, const TYPE &newfangled) { weeded = 0; members.replace(obsolete, newfangled); } // template // //Group::operator Vec &() { // Vec &Group::vec() { // return members; // } // template // //Group::operator const Vec &() const { // const Vec &Group::vec() const { // return members; // } template TYPE &Group::operator[](const int i) { return members[i]; } template TYPE Group::operator[](const int i) const { return members[i]; } // Sort a vector of groups alphabetically by name template int Group::grpcompare(const void *one, const void *two) { Group *grp1 = *(Group**) one; Group *grp2 = *(Group**) two; return grp1->query_name() != grp2->query_name(); // hack! operator!=(CharString, CharString) just returns strcmp() } template void Group::sortgroups(Vec*> &grplist) { ::qsort(&grplist[0], grplist.capacity(), sizeof(Group*), Group::grpcompare); } #endif