00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef MORE_GEN_PARTIAL_ORDERING_H
00032 #define MORE_GEN_PARTIAL_ORDERING_H
00033
00034
00035 #include <more/diag/debug.h>
00036 #include <more/gen/utility.h>
00037 #include <more/gen/iterator.h>
00038 #include <set>
00039
00040
00041 namespace more {
00042 namespace gen {
00043
00044 namespace bits_po {
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 struct partial_ordering_base : noncopyable
00056 {
00057 private:
00058 typedef unsigned int algo_serial_type;
00059 public:
00060 struct element_base;
00061
00062 struct node_base : noncopyable
00063 {
00064 node_base(partial_ordering_base const* context_)
00065 : algo_serial(0), context(context_) {}
00066 std::set<node_base*> m_sups;
00067 std::set<node_base*> m_infs;
00068 algo_serial_type mutable algo_serial;
00069
00070 union algo_cache_type
00071 {
00072 bool as_bool;
00073 int as_int;
00074 void* as_ptr;
00075 } algo_cache;
00076
00077 algo_cache_type& cache() { return algo_cache; }
00078 bool is_cached() { return algo_serial == context->algo_serial; }
00079 void set_cached() { algo_serial = context->algo_serial; }
00080
00081 partial_ordering_base const* context;
00082
00083 typedef std::set<node_base*>::iterator sup_iterator;
00084 typedef std::set<node_base*>::iterator inf_iterator;
00085 };
00086
00087 struct element_base
00088 {
00089 protected:
00090 element_base()
00091 : ptr(0) {}
00092 element_base(node_base* p)
00093 : ptr(p) {}
00094 element_base(element_base const& eb)
00095 : ptr(eb.ptr) {}
00096 element_base& operator=(element_base const& eb) {
00097 ptr = eb.ptr;
00098 return *this;
00099 }
00100 public:
00101 bool operator==(element_base const& rhs) const {
00102 return ptr == rhs.ptr;
00103 }
00104 bool operator!=(element_base const& rhs) const {
00105 return ptr != rhs.ptr;
00106 }
00107 bool operator<(element_base const& rhs) const {
00108 return ptr < rhs.ptr;
00109 }
00110
00111
00112 void clear_cache() const { ptr->context->clear_cache(); }
00113 void set_cached() const { ptr->set_cached(); }
00114 bool is_cached() const { return ptr->is_cached(); }
00115 node_base::algo_cache_type& cache() const { return ptr->cache(); }
00116 friend void check_range(element_base const& eb0,
00117 element_base const& eb1) {
00118 if (eb0.ptr->context != eb1.ptr->context)
00119 throw std::logic_error("more::partial_ordering::element: "
00120 "Elements do not form a valid range.");
00121 }
00122
00123 protected:
00124 mutable node_base* ptr;
00125 friend class partial_ordering_base;
00126 };
00127
00128 partial_ordering_base(node_base* inf, node_base* sup)
00129 : m_min(inf), m_max(sup), algo_serial(0)
00130 {
00131 inf->m_sups.insert(sup);
00132 sup->m_infs.insert(inf);
00133 }
00134
00135 virtual ~partial_ordering_base() {}
00136
00137 void insert_impl(node_base*);
00138 void unlink_impl(node_base*);
00139 static bool preceq_impl(node_base*, node_base*);
00140
00141 private:
00142 static bool preceq_impl_x(node_base*, node_base*);
00143
00144 public:
00145 static bool eq_impl(node_base* x, node_base* y) { return x == y; }
00146 void constrain_prec_impl(node_base* x, node_base* y);
00147 template<typename OutputIterator>
00148 static bool
00149 copy_range_impl(node_base* x, node_base* y, OutputIterator it)
00150 {
00151 assert(x->context == y->context);
00152 x->context->clear_cache();
00153 return copy_range_impl_x(x, y, it);
00154 }
00155 private:
00156 template<typename OutputIterator>
00157 static bool
00158 copy_range_impl_x(node_base*, node_base*, OutputIterator);
00159 public:
00160 template<typename OutputIterator>
00161 static void
00162 copy_supremums_impl(node_base* x, OutputIterator it_out)
00163 {
00164 assert(x != 0);
00165 std::copy(x->m_sups.begin(), x->m_sups.end(), it_out);
00166 }
00167
00168 template<typename OutputIterator>
00169 static void
00170 copy_infimums_impl(node_base* x, OutputIterator it_out)
00171 {
00172 assert(x != 0);
00173 std::copy(x->m_infs.begin(), x->m_infs.end(), it_out);
00174 }
00175
00176 protected:
00177 void clear_cache() const;
00178 void check_integrity();
00179 void check_integrity_from_bottom(node_base*);
00180 void check_integrity_from_top(node_base*);
00181 void dump_structure();
00182
00183
00184
00185 node_base* m_min;
00186 node_base* m_max;
00187 algo_serial_type mutable algo_serial;
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 template<typename T>
00199 struct partial_ordering : private partial_ordering_base
00200 {
00201 typedef T value_type;
00202 typedef typename partial_ordering_base::node_base node_base;
00203
00204 private:
00205 struct node : node_base {
00206 explicit node(partial_ordering_base const* context_)
00207 : node_base(context_) {}
00208 node(partial_ordering_base const* context_, T const& v)
00209 : node_base(context_), value(v) {}
00210 ~node() {}
00211 T value;
00212 };
00213
00214 public:
00215 struct const_element;
00216 struct infimum_iterator;
00217 struct const_infimum_iterator;
00218
00219
00220 struct element : element_base
00221 {
00222 typedef partial_ordering container;
00223 typedef trivial_iterator_tag iterator_category;
00224 typedef void difference_type;
00225 typedef partial_ordering::infimum_iterator infimum_iterator;
00226 typedef partial_ordering::infimum_iterator supremum_iterator;
00227 element() {}
00228 element(node_base* p)
00229 : element_base(p) {}
00230 element(element const& e)
00231 : element_base(e.ptr) {}
00232 element& operator=(element const& e) {
00233 element_base::operator=(e);
00234 return *this;
00235 }
00236 typedef T value_type;
00237 typedef T& reference;
00238 typedef T* pointer;
00239 reference operator*() { return static_cast<node*>(ptr)->value; }
00240 pointer operator->() { return &static_cast<node*>(ptr)->value; }
00241 T const& operator*() const {
00242 return static_cast<node const*>(ptr)->value;
00243 }
00244 T const* operator->() const {
00245 return &(**this);
00246 }
00247 infimum_iterator infimums_begin();
00248 infimum_iterator infimums_end();
00249 supremum_iterator supremums_begin();
00250 supremum_iterator supremums_end();
00251 private:
00252 friend class partial_ordering_base;
00253 friend class partial_ordering;
00254 friend class const_element;
00255 };
00256
00257
00258 struct const_element : element_base
00259 {
00260 typedef partial_ordering container;
00261 typedef trivial_iterator_tag iterator_category;
00262 typedef void difference_type;
00263 typedef partial_ordering::const_infimum_iterator infimum_iterator;
00264 typedef partial_ordering::const_infimum_iterator supremum_iterator;
00265 const_element() {}
00266 const_element(node_base* p)
00267 : element_base(p) {}
00268 const_element(element const& e)
00269 : element_base(e.ptr) {}
00270 const_element(const_element const& e)
00271 : element_base(e.ptr) {}
00272 const_element& operator=(const_element const& e) {
00273 element_base::operator=(e);
00274 return *this;
00275 }
00276 typedef T const value_type;
00277 typedef T const& reference;
00278 typedef T const* pointer;
00279 reference operator*() const {
00280 return static_cast<node const*>(ptr)->value;
00281 }
00282 pointer operator->() const {
00283 return &static_cast<node const*>(ptr)->value;
00284 }
00285 infimum_iterator infimums_begin();
00286 infimum_iterator infimums_end();
00287 supremum_iterator supremums_begin();
00288 supremum_iterator supremums_end();
00289 private:
00290 friend class partial_ordering_base;
00291 friend class partial_ordering;
00292 };
00293
00294 private:
00295
00296
00297 struct const_proxy0
00298 {
00299 const_proxy0() {}
00300 explicit const_proxy0(node_base::inf_iterator it) : it_sub(it) {}
00301 typedef T const value_type;
00302 typedef T const& reference;
00303 typedef T const* pointer;
00304 reference operator*() const {
00305 return static_cast<node const*>(*it_sub)->value;
00306 }
00307 pointer operator->() const { return &(operator*()); }
00308 operator const_element() { return *it_sub; }
00309 bool operator==(const_element const& rhs) const {
00310 return const_element(*it_sub) == rhs;
00311 }
00312 bool operator!=(const_element const& rhs) const {
00313 return const_element(*it_sub) != rhs;
00314 }
00315 friend bool
00316 operator==(const_element const& x, const_proxy0 const& y) {
00317 return y == x;
00318 }
00319 friend bool
00320 operator!=(const_element const& x, const_proxy0 const& y) {
00321 return y != x;
00322 }
00323
00324 protected:
00325 node_base::inf_iterator it_sub;
00326 };
00327
00328 struct proxy0
00329 {
00330 proxy0() {}
00331 explicit proxy0(node_base::inf_iterator it) : it_sub(it) {}
00332 typedef T value_type;
00333 typedef T& reference;
00334 typedef T* pointer;
00335 reference operator*() const {
00336 return static_cast<node*>(*it_sub)->value;
00337 }
00338 pointer operator->() const { return &(operator*()); }
00339 operator element() { return *it_sub; }
00340 bool operator==(element const& rhs) const {
00341 return const_element(*it_sub) == rhs;
00342 }
00343 bool operator!=(element const& rhs) const {
00344 return const_element(*it_sub) != rhs;
00345 }
00346 friend bool
00347 operator==(element const& x, proxy0 const& y) {
00348 return y == x;
00349 }
00350 friend bool
00351 operator!=(element const& x, proxy0 const& y) {
00352 return y != x;
00353 }
00354
00355 protected:
00356 node_base::inf_iterator it_sub;
00357 };
00358
00359 public:
00360
00361
00362
00363 struct infimum_iterator
00364 : private proxy0
00365 {
00366 typedef std::bidirectional_iterator_tag iterator_category;
00367 typedef element value_type;
00368 typedef value_type& reference;
00369 typedef value_type* pointer;
00370 typedef std::ptrdiff_t difference_type;
00371 infimum_iterator() {}
00372 infimum_iterator(node_base::inf_iterator it) : proxy0(it) {}
00373
00374 proxy0& operator*() { return *this; }
00375 proxy0* operator->() { return this; }
00376
00377 infimum_iterator& operator++() { ++it_sub; return *this; }
00378 infimum_iterator& operator--() { --it_sub; return *this; }
00379 infimum_iterator operator++(int) {
00380 infimum_iterator tmp = *this;
00381 ++*this;
00382 return tmp;
00383 }
00384 infimum_iterator operator--(int) {
00385 infimum_iterator tmp = *this;
00386 --*this;
00387 return *this;
00388 }
00389 bool operator==(infimum_iterator const& rhs) const {
00390 return it_sub == rhs.it_sub;
00391 }
00392 bool operator!=(infimum_iterator const& rhs) const {
00393 return it_sub != rhs.it_sub;
00394 }
00395 };
00396
00397
00398
00399 struct const_infimum_iterator
00400 : private const_proxy0
00401 {
00402 typedef std::bidirectional_iterator_tag iterator_category;
00403 typedef const_element value_type;
00404 typedef value_type& reference;
00405 typedef value_type* pointer;
00406 typedef std::ptrdiff_t difference_type;
00407
00408 const_infimum_iterator() {}
00409 const_infimum_iterator(node_base::inf_iterator it)
00410 : const_proxy0(it) {}
00411 const_infimum_iterator(infimum_iterator const& it)
00412 : const_proxy0(it.it_sub) {}
00413
00414 const_proxy0& operator*() { return *this; }
00415 const_proxy0* operator->() { return this; }
00416
00417 const_infimum_iterator& operator++() { ++it_sub; return *this; }
00418 const_infimum_iterator& operator--() { --it_sub; return *this; }
00419 const_infimum_iterator operator++(int) {
00420 const_infimum_iterator tmp = *this;
00421 ++*this;
00422 return tmp;
00423 }
00424 const_infimum_iterator operator--(int) {
00425 const_infimum_iterator tmp = *this;
00426 --*this;
00427 return *this;
00428 }
00429 bool operator==(const_infimum_iterator const& rhs) const {
00430 return it_sub == rhs.it_sub;
00431 }
00432 bool operator!=(const_infimum_iterator const& rhs) const {
00433 return it_sub != rhs.it_sub;
00434 }
00435 };
00436
00437
00438 typedef infimum_iterator supremum_iterator;
00439
00440
00441 typedef const_infimum_iterator const_supremum_iterator;
00442
00443
00444
00445 partial_ordering()
00446 : partial_ordering_base(MORE_NEW(node, this),
00447 MORE_NEW(node, this)) {}
00448
00449
00450 partial_ordering(partial_ordering const& po)
00451 : partial_ordering_base(MORE_NEW(node, this),
00452 MORE_NEW(node, this))
00453 {
00454 insert(po.min(), po.max());
00455 *min() = *po.min();
00456 *max() = *po.max();
00457 }
00458
00459
00460 partial_ordering&
00461 operator=(partial_ordering const& po)
00462 {
00463 clear();
00464 insert(po.min(), po.max());
00465 *min() = *po.min();
00466 *max() = *po.max();
00467 return *this;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 virtual ~partial_ordering()
00483 {
00484 clear();
00485 MORE_DELETE(node, static_cast<node*>(m_min));
00486 MORE_DELETE(node, static_cast<node*>(m_max));
00487 }
00488
00489
00490 void debug_dump() { dump_structure(); }
00491
00492
00493
00494 void clear();
00495
00496
00497
00498 static bool preceq(element e0, element e1)
00499 {
00500 return preceq_impl(e0.ptr, e1.ptr);
00501 }
00502
00503
00504
00505
00506 static bool eq(element e0, element e1)
00507 {
00508 return eq_impl(e0.ptr, e1.ptr);
00509 }
00510
00511
00512 bool constrain_prec(element e0, element e1)
00513 {
00514 if (prec(e0, e1))
00515 return true;
00516 else if (preceq(e1, e0))
00517 return false;
00518 else {
00519 constrain_prec_impl(e0.ptr, e1.ptr);
00520 return true;
00521 }
00522 }
00523
00524 private:
00525 static node_base* copy_caching(node_base*, node_base*, node_base*);
00526
00527
00528 public:
00529
00530 element insert(T const& value)
00531 {
00532 node* ptr = MORE_NEW(node, this, value);
00533 insert_impl(ptr);
00534 return ptr;
00535 }
00536
00537
00538 element insert()
00539 {
00540 node* ptr = MORE_NEW(node, this);
00541 insert_impl(ptr);
00542 return ptr;
00543 }
00544
00545
00546
00547 void insert(const_element e_min, const_element e_max)
00548 {
00549 insert(e_min, e_max, min(), max());
00550 }
00551
00552
00553
00554 void insert(const_element e_min, const_element e_max,
00555 element e_min_dest, element e_max_dest)
00556 {
00557 if (e_min == e_max) return;
00558 if (e_min_dest == e_max_dest)
00559 throw std::logic_error("more::partial_ordering::insert: "
00560 "Invalid destination range.");
00561 e_min.clear_cache();
00562 for (node_base::sup_iterator it = e_min.ptr->m_sups.begin();
00563 it != e_min.ptr->m_sups.end(); ++it) {
00564 node_base* node_new
00565 = copy_caching(*it, e_max.ptr, e_max_dest.ptr);
00566 e_min_dest.ptr->m_sups.insert(node_new);
00567 node_new->m_infs.insert(e_min_dest.ptr);
00568 }
00569 }
00570
00571
00572 void erase(element e)
00573 {
00574 unlink_impl(e.ptr);
00575 delete e.ptr;
00576 }
00577
00578
00579
00580 const_element min() const { return m_min; }
00581
00582
00583
00584 const_element max() const { return m_max; }
00585
00586
00587
00588 element min() { return m_min; }
00589
00590
00591
00592 element max() { return m_max; }
00593
00594
00595
00596
00597 template<typename OutputIterator>
00598 static void
00599 copy_range(element e0, element e1, OutputIterator it_out)
00600 {
00601 partial_ordering<T>::copy_range_impl(e0.ptr, e1.ptr, it_out);
00602 }
00603 template<typename OutputIterator>
00604 static void
00605 copy_range(const_element e0, const_element e1,
00606 OutputIterator it_out)
00607 {
00608 if (0) { *it_out = e0; }
00609 partial_ordering<T>::copy_range_impl(e0.ptr, e1.ptr, it_out);
00610 }
00611
00612
00613
00614
00615
00616
00617
00618 template<typename OutputIterator>
00619 static void
00620 copy_supremums(element e, OutputIterator it_out)
00621 {
00622 partial_ordering<T>::copy_supremums_impl(e.ptr, it_out);
00623 }
00624
00625 template<typename OutputIterator>
00626 static void
00627 copy_supremums(const_element e, OutputIterator it_out)
00628 {
00629 if (0) { *it_out = e; }
00630 partial_ordering<T>::copy_supremums_impl(e.ptr, it_out);
00631 }
00632
00633
00634
00635
00636
00637 template<typename OutputIterator>
00638 static void
00639 copy_infimums(element e, OutputIterator it_out)
00640 {
00641 partial_ordering<T>::copy_infimums_impl(e.ptr, it_out);
00642 }
00643 template<typename OutputIterator>
00644 static void
00645 copy_infimums(const_element e, OutputIterator it_out)
00646 {
00647 if (0) { *it_out = e; }
00648 partial_ordering<T>::copy_infimums_impl(e.ptr, it_out);
00649 }
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 static std::pair<const_infimum_iterator, const_infimum_iterator>
00660 infimum_range(const_element x)
00661 {
00662 return std::make_pair(const_infimum_iterator(x.ptr->m_infs.begin()),
00663 const_infimum_iterator(x.ptr->m_infs.end()));
00664 }
00665
00666
00667
00668 static std::pair<const_supremum_iterator, const_supremum_iterator>
00669 supremum_range(const_element x)
00670 {
00671 return std::make_pair(const_supremum_iterator(x.ptr->m_sups.begin()),
00672 const_supremum_iterator(x.ptr->m_sups.end()));
00673 }
00674
00675
00676
00677 static std::pair<infimum_iterator, infimum_iterator>
00678 infimum_range(element x)
00679 {
00680 return std::make_pair(infimum_iterator(x.ptr->m_infs.begin()),
00681 infimum_iterator(x.ptr->m_infs.end()));
00682 }
00683
00684
00685
00686 static std::pair<supremum_iterator, supremum_iterator>
00687 supremum_range(element x)
00688 {
00689 return std::make_pair(supremum_iterator(x.ptr->m_sups.begin()),
00690 supremum_iterator(x.ptr->m_sups.end()));
00691 }
00692 };
00693
00694 template<typename T>
00695 inline typename partial_ordering<T>::element::supremum_iterator
00696 partial_ordering<T>::element::supremums_begin()
00697 {
00698 return ptr->m_sups.begin();
00699 }
00700 template<typename T>
00701 inline typename partial_ordering<T>::element::supremum_iterator
00702 partial_ordering<T>::element::supremums_end()
00703 {
00704 return ptr->m_sups.end();
00705 }
00706
00707 template<typename T>
00708 inline typename partial_ordering<T>::element::infimum_iterator
00709 partial_ordering<T>::element::infimums_begin()
00710 {
00711 return ptr->m_infs.begin();
00712 }
00713 template<typename T>
00714 inline typename partial_ordering<T>::element::infimum_iterator
00715 partial_ordering<T>::element::infimums_end()
00716 {
00717 return ptr->m_infs.end();
00718 }
00719
00720 template<typename T>
00721 inline typename partial_ordering<T>::const_element::supremum_iterator
00722 partial_ordering<T>::const_element::supremums_begin()
00723 {
00724 return ptr->m_sups.begin();
00725 }
00726 template<typename T>
00727 inline typename partial_ordering<T>::const_element::supremum_iterator
00728 partial_ordering<T>::const_element::supremums_end()
00729 {
00730 return ptr->m_sups.end();
00731 }
00732
00733 template<typename T>
00734 inline typename partial_ordering<T>::const_element::infimum_iterator
00735 partial_ordering<T>::const_element::infimums_begin()
00736 {
00737 return ptr->m_infs.begin();
00738 }
00739 template<typename T>
00740 inline typename partial_ordering<T>::const_element::infimum_iterator
00741 partial_ordering<T>::const_element::infimums_end()
00742 {
00743 return ptr->m_infs.end();
00744 }
00745
00746 template<typename Element>
00747 std::pair< typename Element::supremum_iterator,
00748 typename Element::supremum_iterator >
00749 supremums(Element e)
00750 {
00751 return std::make_pair(e.supremums_begin(),
00752 e.supremums_end());
00753 }
00754 template<typename Element>
00755 std::pair< typename Element::infimum_iterator,
00756 typename Element::infimum_iterator >
00757 infimums(Element e)
00758 {
00759 return std::make_pair(e.infimums_begin(),
00760 e.infimums_end());
00761 }
00762
00763
00764
00765
00766 template<typename Element>
00767 inline bool preceq(Element e0, Element e1)
00768 {
00769 typedef typename Element::container container;
00770 return container::preceq(e0, e1);
00771 }
00772
00773
00774 template<typename Element>
00775 inline bool prec(Element e0, Element e1)
00776 {
00777 return e0 != e1 && preceq(e0, e1);
00778 }
00779
00780
00781 template<typename Element>
00782 inline bool succeq(Element e0, Element e1) { return preceq(e1, e0); }
00783
00784
00785 template<typename Element>
00786 inline bool succ(Element e0, Element e1) { return prec(e1, e0); }
00787
00788
00789 }
00790 using bits_po::partial_ordering;
00791
00792
00793
00794 }}
00795
00796 #include <more/bits/partial_ordering.tcc>
00797
00798 #endif