Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/gen/partial_ordering.h

Go to the documentation of this file.
00001 //  more/partial_ordering.h -- container representing a partial ordering
00002 //  Copyright (C) 2001--2002  Petter Urkedal
00003 //
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 //
00028 //  $Id: partial_ordering.h,v 1.2 2002/08/24 13:50:58 petter_urkedal Exp $
00029 
00030 
00031 #ifndef MORE_GEN_PARTIAL_ORDERING_H
00032 #define MORE_GEN_PARTIAL_ORDERING_H
00033 
00034 //#define MORE_CHECK_ALLOCATIONS 1
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 ///\if bits
00044 namespace bits_po {
00045 ///\endif
00046 
00047   //
00048   // -- partial_ordering_base --
00049   //
00050 
00051   /** \class partial_ordering_base partial_ordering.h \
00052    **        more/gen/partial_ordering.h
00053    **
00054    ** Helper class. */
00055   struct partial_ordering_base : noncopyable/*XXX todo*/
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; // need algo_serial
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           /** not stabilized yet */
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       // private:
00184 
00185       node_base* m_min;
00186       node_base* m_max;
00187       algo_serial_type mutable algo_serial;
00188   };
00189 
00190 
00191   //
00192   //  -- partial_ordering --
00193   //
00194 
00195   /** \class partial_ordering partial_ordering.h more/gen/partial_ordering.h
00196    **
00197    ** A container which provides a partially ordering of its elements. */
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         /** an element of the ordering */
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         /** an element of the ordering with constant value */
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         // a proxy used in infimum_iterator to emulate const_element
00296         // needed for operator->, and may accelerate operator*.
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         /** A bidirectional iterator used by infimum_range. The \c
00361          * operator* (and operator->) returns a proxy which must be
00362          * cast if passed to a templated argument. */
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         /** A bidirectional iterator used by infimum_range. See \c
00398          * infimum_iterator. */
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         /** A bidirectional iterator used by supremum_range. */
00438         typedef infimum_iterator supremum_iterator;
00439 
00440         /** A bidirectional iterator used by supremum_range. */
00441         typedef const_infimum_iterator const_supremum_iterator;
00442 
00443         /** construct a partial ordering with only infimun and
00444          * supremum elements. */
00445         partial_ordering()
00446             : partial_ordering_base(MORE_NEW(node, this),
00447                                     MORE_NEW(node, this)) {}
00448 
00449         /** contruct a deep copy. */
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         /** assign a deep copy. */
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         /** compare container structure and valued using
00471          * value_type::operator==. */
00472 //      bool operator==(partial_ordering const& rhs) const {
00473 //          clear_cache();
00474 //          return compare_caching() == 0;
00475 //      }
00476 //      bool operator!=(partial_ordering const& rhs) const {
00477 //          return !(*this == rhs);
00478 //      }
00479 
00480         /** destructs the partial ordering. All elements created from
00481          * the ordering will be invalidated. */
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         /** Not for production code. */
00490         void debug_dump() { dump_structure(); }
00491 
00492         /** clear a partial ordering. All elements of the ordering are
00493          * invalidated. */
00494         void clear();
00495 
00496         /** returns true iff \f$e_0\sqsubseteq e_1\f$ is implied by
00497          * the given constraints. */
00498         static bool preceq(element e0, element e1)
00499         {
00500             return preceq_impl(e0.ptr, e1.ptr);
00501         }
00502 
00503         /** returns true iff \f$e_0=e_1\f$ is implied by the given
00504          * contraits. Equivalent to <tt>prec(e0, e1) && preceq(e1,
00505          * e0)</tt> */
00506         static bool eq(element e0, element e1)
00507         {
00508             return eq_impl(e0.ptr, e1.ptr);
00509         }
00510 
00511         /** imposes the constraint \f$e_0\sqsubseteq e_1\f$. */
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 //      static int compare_caching(node_base*, node_base*, node_base*);
00527 
00528       public:
00529         /** create a new element with the given value. */
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         /** create a new default constructed element. */
00538         element insert()
00539         {
00540             node* ptr = MORE_NEW(node, this);
00541             insert_impl(ptr);
00542             return ptr;
00543         }
00544 
00545         /** insert a range of values. Equivalent to <tt>insert(e_min,
00546          * e_max, min(), max())</tt>. */
00547         void insert(const_element e_min, const_element e_max)
00548         {
00549             insert(e_min, e_max, min(), max());
00550         }
00551 
00552         /** insert nodes in (e_min, e_max) into (e_min_dest,
00553          * e_max_dest). */
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         /** erase an element. Unimplemented, does nothing. */
00572         void erase(element e)
00573         {
00574             unlink_impl(e.ptr);
00575             delete e.ptr;
00576         }
00577 
00578         /** returns the element which is less than any other
00579          * element. It is dereferenceable. */
00580         const_element min() const { return m_min; }
00581 
00582         /** returns the element which is greater than any other
00583          * element. It is derferenceable. */
00584         const_element max() const { return m_max; }
00585 
00586         /** returns the element which is less than any other element.
00587          * It is dereferenceable with an lvalue as the result. */
00588         element min() { return m_min; }
00589 
00590         /** returns the element which is greater than any other element.
00591          * It is dereferenceable with an lvalue as the result. */
00592         element max() { return m_max; }
00593 
00594         //@{
00595         /** copies to \c it_out the set of elements
00596          * \f$\{z : x\sqsubseteq z \sqsubseteq y \wedge z \neq y\}\f$. */
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; } // constness check for iterator
00609               partial_ordering<T>::copy_range_impl(e0.ptr, e1.ptr, it_out);
00610           }
00611         //@}
00612 
00613         //@{
00614         /** copies to \c it_out the set of elements \f$\{z : x\sqsubseteq z
00615          * \wedge (x\sqsubseteq y\sqsubseteq z\Rightarrow x=y\vee
00616          * x=z)\}\f$. In contrast to full orderings, there may be more than
00617          * one element fulfilling this condition. */
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; } // constness check for iterator
00630               partial_ordering<T>::copy_supremums_impl(e.ptr, it_out);
00631           }
00632         //@}
00633         //@{
00634         /** copyies to \c it_out the set of elements \f$\{z : z\sqsubseteq
00635          * x\wedge (z\sqsubseteq y\sqsubseteq x\Rightarrow y=x\vee
00636          * y=z)\}\f$. */
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; } // constness check for iterator
00648               partial_ordering<T>::copy_infimums_impl(e.ptr, it_out);
00649           }
00650         //@}
00651 //      template<typename PrecEqPredicate, typename OutputIterator>
00652 //        static void copy_infimums(value_type const&, PrecEqPredicate,
00653 //                                  OutputIterator);
00654 
00655         /** Returns a range of the infimums of \c x. Note that the
00656          * value_type of the iterator is \c const_element, so a double
00657          * dereference is needed to obtain a \c value_type of this
00658          * container. */
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         /** Returns a range of the supremums of \c x. See \c
00667          * infimum_range(const_element)  const. */
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         /** Returns a range of the infimums of \c x. See \c
00676          * infimum_range(const_element) const. */
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         /** Returns a range of the supremums of \c x. See \c
00685          * infimum_range(const_element) const. */
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   /** returns true if \f$e_0\sqsubseteq e_1\f$. */
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   /** returns true if \f$e_0\sqsubset e_1\f$. */
00774   template<typename Element>
00775     inline bool prec(Element e0, Element e1)
00776     {
00777         return e0 != e1 && preceq(e0, e1);
00778     }
00779 
00780   /** returns true if \f$e_0\sqsupseteq e_1\f$. */
00781   template<typename Element>
00782     inline bool succeq(Element e0, Element e1) { return preceq(e1, e0); }
00783 
00784   /** returns true if \f$e_0\sqsupset e_1\f$. */
00785   template<typename Element>
00786     inline bool succ(Element e0, Element e1) { return prec(e1, e0); }
00787 
00788   ///\if bits
00789 }
00790   using bits_po::partial_ordering;
00791   ///\endif
00792   // The rest is Koenig lookup.
00793 
00794 }} // more::gen
00795 
00796 #include <more/bits/partial_ordering.tcc>
00797 
00798 #endif

Generated on Sat Sep 7 19:11:14 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.