dlvhex  2.5.0
include/dlvhex2/Set.h
Go to the documentation of this file.
00001 /* dlvhex -- Answer-Set Programming with external interfaces.
00002  * Copyright (C) 2005-2007 Roman Schindlauer
00003  * Copyright (C) 2006-2015 Thomas Krennwallner
00004  * Copyright (C) 2009-2016 Peter Schüller
00005  * Copyright (C) 2011-2016 Christoph Redl
00006  * Copyright (C) 2015-2016 Tobias Kaminski
00007  * Copyright (C) 2015-2016 Antonius Weinzierl
00008  *
00009  * This file is part of dlvhex.
00010  *
00011  * dlvhex is free software; you can redistribute it and/or modify it
00012  * under the terms of the GNU Lesser General Public License as
00013  * published by the Free Software Foundation; either version 2.1 of
00014  * the License, or (at your option) any later version.
00015  *
00016  * dlvhex is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with dlvhex; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00034 #ifndef SET_HPP_INCLUDED__09122011
00035 #define SET_HPP_INCLUDED__09122011
00036 
00037 #include <iterator>
00038 #include <boost/foreach.hpp>
00039 #include <boost/unordered_map.hpp>
00040 #include "dlvhex2/DynamicVector.h"
00041 
00042 template<typename T>
00043 class Set;
00044 
00048 template<typename T>
00049 class insert_set_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
00050 {
00051     protected:
00052         Set<T>& set;
00053     public:
00054         insert_set_iterator(Set<T>& s) : set(s) {
00055         }
00056 
00057         insert_set_iterator& operator=(const typename Set<T>::value_type& v) {
00058             set.insert(v);
00059             return *this;
00060         }
00061 
00062         insert_set_iterator& operator*() {
00063             return *this;
00064         }
00065 
00066         insert_set_iterator& operator++() {
00067             return *this;
00068         }
00069 
00070         insert_set_iterator operator++(int) {
00071             return *this;
00072         }
00073 };
00074 
00078 template<typename T>
00079 class const_set_iterator : public std::iterator<std::input_iterator_tag, T, ptrdiff_t, const T*, const T&>
00080 {
00081     protected:
00082         const Set<T>& set;
00083         int loc;
00084     public:
00085         const_set_iterator(const Set<T>& s, int l = 0) : set(s), loc(l) {
00086         }
00087 
00088         inline const T& operator*() const
00089         {
00090             return set.getData()[loc];
00091         }
00092 
00093         inline const T* operator->() const
00094         {
00095             return &(set.getData()[loc]);
00096         }
00097 
00098         inline const_set_iterator& operator++() {
00099             ++loc;
00100             return *this;
00101         }
00102 
00103         inline const_set_iterator operator++(int) {
00104             const_set_iterator<T> old(*this);
00105             operator++();
00106             return old;
00107         }
00108 
00109         inline const_set_iterator& operator--() {
00110             --loc;
00111             return *this;
00112         }
00113 
00114         inline const_set_iterator operator--(int) {
00115             const_set_iterator<T> old(*this);
00116             operator--();
00117             return old;
00118         }
00119 
00120         inline const_set_iterator operator+(int i) const
00121         {
00122             return const_set_iterator<T>(set, loc + 1);
00123         }
00124 
00125         inline const_set_iterator operator+(const_set_iterator& it) const
00126         {
00127             return const_set_iterator<T>(set, loc + it.loc);
00128         }
00129 
00130         inline const_set_iterator operator-(int i) const
00131         {
00132             return const_set_iterator<T>(set, loc - i);
00133         }
00134 
00135         inline const_set_iterator operator-(const_set_iterator& it) const
00136         {
00137             return const_set_iterator<T>(set, loc - it.loc);
00138         }
00139 
00140         inline operator const int() const
00141         {
00142             return loc;
00143         }
00144 
00145         inline bool operator==(const_set_iterator const& sit2) const
00146         {
00147             return loc == sit2.loc;
00148         }
00149 
00150         inline bool operator!=(const_set_iterator const& sit2) const
00151         {
00152             return loc != sit2.loc;
00153         }
00154 };
00155 
00159 template<typename T>
00160 class set_iterator : public std::iterator<std::input_iterator_tag, T, ptrdiff_t, T*, T&>
00161 {
00162     protected:
00163         Set<T>& set;
00164         int loc;
00165     public:
00166         set_iterator(Set<T>& s, int l = 0) : set(s), loc(l) {
00167         }
00168 
00169         inline T& operator*() {
00170             return set.getData()[loc];
00171         }
00172 
00173         inline T* operator->() {
00174             return &(set.getData()[loc]);
00175         }
00176 
00177         inline set_iterator& operator++() {
00178             ++loc;
00179             return *this;
00180         }
00181 
00182         inline set_iterator operator++(int) {
00183             set_iterator<T> old(*this);
00184             operator++();
00185             return old;
00186         }
00187 
00188         inline set_iterator& operator--() {
00189             --loc;
00190             return *this;
00191         }
00192 
00193         inline set_iterator operator--(int) {
00194             set_iterator<T> old(*this);
00195             operator--();
00196             return old;
00197         }
00198 
00199         inline set_iterator operator+(int i) const
00200         {
00201             return set_iterator<T>(set, loc + i);
00202         }
00203 
00204         inline set_iterator operator+(set_iterator& it) const
00205         {
00206             return set_iterator<T>(set, loc + it.loc);
00207         }
00208 
00209         inline set_iterator operator-(int i) const
00210         {
00211             return set_iterator<T>(set, loc - i);
00212         }
00213 
00214         inline set_iterator operator-(set_iterator& it) const
00215         {
00216             return set_iterator<T>(set, loc - it.loc);
00217         }
00218 
00219         inline operator const int() const
00220         {
00221             return loc;
00222         }
00223 
00224         inline bool operator==(set_iterator const& sit2) const
00225         {
00226             return loc == sit2.loc;
00227         }
00228 
00229         inline bool operator!=(set_iterator const& sit2) const
00230         {
00231             return loc != sit2.loc;
00232         }
00233 };
00234 
00236 template<typename T>
00237 class Set
00238 {
00239     private:
00240         T* data;
00241 
00242         int allocSize;
00243         int rsize;
00244         int increase;
00245 
00247         void grow() {
00248             allocSize += increase;
00249             data = (T*)realloc(data, sizeof(T) * allocSize);
00250         }
00251 
00255         void grow(int minSize) {
00256             allocSize = minSize % increase == 0
00257                 ? minSize
00258                 : (minSize / increase + 1) * increase;
00259             data = (T*)realloc(data, sizeof(T) * allocSize);
00260         }
00261 
00265         int binarySearch(T e) const
00266         {
00267             if (rsize == 0) return 0;
00268 
00269             int lower = 0;
00270             int upper = rsize - 1;
00271             int pos = (lower + upper) / 2;
00272 
00273             while (data[pos] != e) {
00274                 if (e < data[pos]) {
00275                     if (pos > lower) {
00276                         upper = pos - 1;
00277                     }
00278                     else {
00279                         // element is not contained: return insert location
00280                         return pos;
00281                     }
00282                 }
00283                 else {
00284                     if (pos < upper) {
00285                         lower = pos + 1;
00286                     }
00287                     else {
00288                         // element is not contained: return insert location
00289                         return pos + 1;
00290                     }
00291                 }
00292                 pos = (lower + upper) / 2;
00293             }
00294             // element is contained
00295             return pos;
00296         }
00297 
00298     public:
00299         typedef set_iterator<T> iterator;
00300         typedef const_set_iterator<T> const_iterator;
00301         typedef T value_type;
00302         typedef const T& const_reference;
00303 
00307         Set(int initialSize = 0, int inc = 10) : increase(inc), rsize(0) {
00308             if (initialSize == 0) {
00309                 data = 0;
00310             }
00311             else {
00312                 data = (T*)realloc(0, sizeof(T) * initialSize);
00313             }
00314             allocSize = initialSize;
00315         }
00316 
00319         Set(const Set<T>& s2) {
00320             data = (T*)realloc(0, sizeof(T) * s2.allocSize);
00321             allocSize = s2.allocSize;
00322             increase = s2.increase;
00323             rsize = s2.rsize;
00324             memcpy(data, s2.data, sizeof(T) * rsize);
00325         }
00326 
00328         virtual ~Set() {
00329             if (data) free(data);
00330             data = 0;
00331         }
00332 
00336         inline bool contains(T e) const
00337         {
00338             int p =  binarySearch(e);
00339             return (p < rsize) && (data[p] == e);
00340         }
00341 
00346         inline int count(T e) const
00347         {
00348             return contains(e) ? 1 : 0;
00349         }
00350 
00353         inline void insert(T e) {
00354             // find location for insertion
00355             int p = binarySearch(e);
00356                                  // already contained
00357             if (p < rsize && data[p] == e) return;
00358 
00359             if (rsize == allocSize) {
00360                 grow();
00361             }
00362 
00363             // shift
00364             memmove(&(data[p + 1]), &(data[p]), sizeof(T) * (rsize - p));
00365 
00366             // insert
00367             data[p] = e;
00368             rsize++;
00369         }
00370 
00374         template<typename _Iter>
00375         inline void insert(_Iter begin, _Iter end) {
00376             grow(size() + (end - begin));
00377             for (_Iter it = begin; it != end; ++it) {
00378                 insert(*it);
00379             }
00380         }
00381 
00384         inline void erase(T e) {
00385             // find element
00386             int p = binarySearch(e);
00387                                  // not contained
00388             if (p >= rsize) return;
00389                                  // not contained
00390             if (data[p] != e) return;
00391 
00392             // shift
00393             memmove(&(data[p]), &(data[p + 1]), sizeof(T) * (rsize - (p + 1)));
00394 
00395             rsize--;
00396         }
00397 
00401         inline set_iterator<T> find(T e) {
00402             // find element
00403             int p = binarySearch(e);
00404                                  // not contained
00405             if (p >= rsize) return end();
00406                                  // not contained
00407             if (data[p] != e) return end();
00408             return set_iterator<T>(*this, p);
00409         }
00410 
00414         inline const_set_iterator<T> find(T e) const
00415         {
00416             // find element
00417             int p = binarySearch(e);
00418                                  // not contained
00419             if (p >= rsize) return ((const Set<T>*)this)->end();
00420                                  // not contained
00421             if (data[p] != e) return ((const Set<T>*)this)->end();
00422             return const_set_iterator<T>(*this, p);
00423         }
00424 
00427         bool empty() const
00428         {
00429             return rsize == 0;
00430         }
00431 
00433         void clear() {
00434             rsize = 0;
00435         }
00436 
00439         set_iterator<T> begin() {
00440             return set_iterator<T>(*this, 0);
00441         }
00442 
00445         set_iterator<T> end() {
00446             return set_iterator<T>(*this, rsize);
00447         }
00448 
00451         const_set_iterator<T> begin() const
00452         {
00453             return const_set_iterator<T>(*this, 0);
00454         }
00455 
00458         const_set_iterator<T> end() const
00459         {
00460             return const_set_iterator<T>(*this, rsize);
00461         }
00462 
00466         inline T& operator[](int i) {
00467             return data[i];
00468         }
00469 
00473         inline const T& operator[](int i) const
00474         {
00475             return data[i];
00476         }
00477 
00482         inline int size() const
00483         {
00484             return rsize;
00485         }
00486 
00489         T* getData() {
00490             return data;
00491         }
00492 
00495         const T* getData() const
00496         {
00497             return data;
00498         }
00499 
00503         Set<T>& operator=(const Set<T>& s2) {
00504             clear();
00505             grow(s2.size());
00506             rsize = s2.rsize;
00507             memcpy(data, s2.data, sizeof(T) * rsize);
00508             return *this;
00509         }
00510 };
00511 
00513 template<typename T>
00514 struct SortElement
00515 {
00517     long index;
00519     T elem;
00520 
00522     SortElement() {
00523     }
00524 
00528     SortElement(int i, T el) : index(i), elem(el) {
00529     }
00530 
00534     bool operator<(const SortElement<T>& el2) const
00535     {
00536         return index < el2.index;
00537     }
00538 
00542     bool operator>(const SortElement<T>& el2) const
00543     {
00544         return index > el2.index;
00545     }
00546 
00551     bool operator==(const SortElement<T>& el2) const
00552     {
00553         return index == el2.index;
00554     }
00555 
00559     bool operator!=(const SortElement<T>& el2) const
00560     {
00561         return index != el2.index;
00562     }
00563 };
00564 
00566 template<typename T, typename H>
00567 class OrderedSet
00568 {
00569     private:
00571         DynamicVector<T, long> os;
00573         long c;
00574 
00576         void renumber() {
00577             typedef SortElement<T> SortEl;
00578             std::vector<SortElement<T> > sorted;
00579             sorted.reserve(os.size());
00580 
00581             for (T i = 0; i < os.size(); ++i) {
00582                 if (os.find(i) != os.end()) {
00583                     sorted.push_back(SortEl(os[i], i));
00584                 }
00585             }
00586 
00587             std::sort(sorted.begin(), sorted.end());
00588 
00589             c = 0;
00590             BOOST_FOREACH (SortEl se, sorted) {
00591                 os[se.elem] = c++;
00592             }
00593         }
00594 
00595     public:
00597         OrderedSet() : c(0) {
00598         }
00599 
00602         inline void insert(T el) {
00603             if (c >= 1000000000) {
00604                 renumber();
00605             }
00606             os[el] = c++;
00607         }
00608 
00611         inline void erase(T el) {
00612             os.erase(el);
00613         }
00614 
00620         long getInsertionIndex(T el) {
00621             return os[el];
00622         }
00623 
00629         inline int compare(T el1, T el2) {
00630             if (getInsertionIndex(el1) < getInsertionIndex(el2)) return -1;
00631             else if (getInsertionIndex(el1) > getInsertionIndex(el2)) return +1;
00632             else return 0;
00633         }
00634 
00636         void resize(int s) {
00637         }
00638 };
00639 
00640 // compatibility with BOOST_FOREACH
00641 namespace boost
00642 {
00643     template<typename T>
00644         struct range_mutable_iterator< Set<T> >
00645     {
00646         typedef set_iterator<T> type;
00647     };
00648 
00649     template<typename T>
00650         struct range_const_iterator< Set<T> >
00651     {
00652         typedef const_set_iterator<T> type;
00653     };
00654 }
00655 #endif
00656 
00657 // vim:expandtab:ts=4:sw=4:
00658 // mode: C++
00659 // End: