/*ident "@(#)Block:demos/Blockset.h 3.1" */ /****************************************************************************** * * C++ Standard Components, Release 3.0. * * Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc. * Copyright (c) 1988, 1989, 1990 AT&T. All Rights Reserved. * * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System * Laboratories, Inc. The copyright notice above does not evidence * any actual or intended publication of such source code. * ******************************************************************************/ /* * Blockset - implementation of parameterized Set class. * * This implementation is based on Block Algorithm functions. * The code in this example is taken directly from the tutorial * "No more array errors" by John Isner. */ #ifndef BLOCKSETH #define BLOCKSETH #include #include #include #include template class Blocksetiter; template class Blockset { friend class Blocksetiter; private: Block b; unsigned n; void check(); public: // Constructors, destructor Blockset() : b(100), n(0) { } Blockset(const T& t0) : b(100), n(1) { set_insert(t0, &b[0], &b[0]); } Blockset(const T& t0, const T& t1) : b(100), n(2) { set_insert(t0, &b[0], &b[0]); set_insert(t1, &b[0], &b[1]); } Blockset(const T& t0, const T& t1, const T& t2) : b(100), n(3) { set_insert(t0, &b[0], &b[0]); set_insert(t1, &b[0], &b[1]); set_insert(t2, &b[0], &b[2]); } Blockset(const T& t0, const T& t1, const T& t2, const T& t3):b(100), n(4) { set_insert(t0, &b[0], &b[0]); set_insert(t1, &b[0], &b[1]); set_insert(t2, &b[0], &b[2]); set_insert(t3, &b[0], &b[3]); } Blockset(const Blockset& s) : b(s.b), n(s.n) { } ~Blockset(){ } // Size int size() const { return n; } int size_unique() const { return size(); } operator const void*() const { return n>0?this:0; } // Assignment Blockset& operator=(const Blockset& s) { b = s.b; n = s.n; return *this; } // Relations int operator==(const Blockset& s) const { return (n==s.n && mismatch(&b[0], &b[n], &(s.b[0]), &(b[s.n]))==0); } int operator!=(const Blockset& s) const { return !(*this==s); } int operator<=(const Blockset& s) const { return n<=s.n && mismatch(&b[0], &b[n], &(s.b[0]), &(s.b[s.n]))==0; } int operator<(const Blockset& s) const { return n=(const Blockset& s) const { return !(*this(const Blockset& s) const { return !(*this<=s); } // Membership const T* contains(const T& t) const { return bin_search(t, &b[0], &b[n]); } unsigned count(const T& t) const { return bin_search(t, &b[0], &b[n])!=0; } // Insert and remove const T* insert(const T& t, unsigned count=1) { const T* result=0; if( count>0 ) { b.reserve(n); result=set_insert(t, &b[0], &b[(int)n]); n++; } return result; } unsigned remove(const T& t, unsigned count=1) { unsigned result=0; if( count>0 && set_remove(t, &b[0], &b[n])<&b[n] ) { n--; result=1; } return result; } unsigned remove_all(const T& t) { return remove(t, 1); } unsigned remove_all() { unsigned result = n; n = 0; return result; } // Select an arbitrary element const T* select() const { return random(&b[0], &b[n]); } // Blockset algebra Blockset operator|(const Blockset& s) const { Blockset result; result.b.reserve(n + s.n - 1); result.n = set_union(&b[0], &b[n], &(s.b[0]), &(s.b[s.n]), &(result.b[0])) - &(result.b[0]); return result; } Blockset operator-(const Blockset& s) const { Blockset result; result.b.reserve(n-1); result.n = set_diff(&b[0], &b[n], &(s.b[0]), &(s.b[s.n]), &(result.b[0])) - &(result.b[0]); return result; } Blockset operator&(const Blockset& s) const { Blockset result; result.b.reserve(n + s.n -1); result.n = set_inter(&b[0], &b[n], &(s.b[0]), &(s.b[s.n]), &(result.b[0])) - &(result.b[0]); return result; } Blockset operator^(const Blockset& s) const { Blockset result; result.b.reserve(n + s.n -1); result.n = set_sdiff(&b[0], &b[n], &(s.b[0]), &(s.b[s.n]), &(result.b[0])) - &(result.b[0]); return result; } }; // Blockset iterators template class Blocksetiter { const Blockset* sp; unsigned i; public: Blocksetiter(const Blockset& s) : sp(&s), i(0) { } const T* next() { return (in) ? &(((Blockset*)sp)->b[(int)i++]) : 0; } void reset() { i=0; } }; template ostream& operator<<(ostream& os, const Blockset& s){ os << "{"; Blocksetiter it(s); const T* tp; int first=1; while( tp = it.next() ){ if( first ){ first=0; }else{ os << ','; } os << *tp; } os << '}'; return os; } #endif