dlvhex
2.5.0
|
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: