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

more/gen/unifying_partial_ordering.h

Go to the documentation of this file.
00001 //  more/unifying_partial_ordering.h -- container representing a
00002 //                                      partial ordering
00003 //  Copyright (C) 2001--2002  Petter Urkedal
00004 //
00005 //  This file is free software; you can redistribute it and/or modify
00006 //  it under the terms of the GNU General Public License as published by
00007 //  the Free Software Foundation; either version 2 of the License, or
00008 //  (at your option) any later version.
00009 //
00010 //  This file is distributed in the hope that it will be useful,
00011 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 //  GNU General Public License for more details.
00014 //
00015 //  You should have received a copy of the GNU General Public License
00016 //  along with this program; if not, write to the Free Software
00017 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //  As a special exception, you may use this file as part of a free
00020 //  software library without restriction.  Specifically, if other files
00021 //  instantiate templates or use macros or inline functions from this
00022 //  file, or you compile this file and link it with other files to
00023 //  produce an executable, this file does not by itself cause the
00024 //  resulting executable to be covered by the GNU General Public
00025 //  License.  This exception does not however invalidate any other
00026 //  reasons why the executable file might be covered by the GNU General
00027 //  Public License.
00028 //
00029 //  $Id: unifying_partial_ordering.h,v 1.2 2002/08/24 13:50:58 petter_urkedal Exp $
00030 
00031 
00032 #ifndef MORE_GEN_UNIFYING_PARTIAL_ORDERING_H
00033 #define MORE_GEN_UNIFYING_PARTIAL_ORDERING_H
00034 
00035 //#define MORE_CHECK_ALLOCATIONS 1
00036 #include <more/diag/debug.h>
00037 #include <more/gen/link.h>
00038 #include <more/gen/utility.h>
00039 #include <more/gen/iterator.h>
00040 #include <set>
00041 
00042 
00043 namespace more {
00044 namespace gen {
00045 ///\if bits
00046 namespace bits_upo {
00047 ///\endif
00048 
00049   //
00050   // -- unifying_partial_ordering_base --
00051   //
00052 
00053   /** \class unifying_partial_ordering_base unifying_partial_ordering.h \
00054    **        more/gen/unifying_partial_ordering.h
00055    **
00056    ** Helper class. */
00057   struct unifying_partial_ordering_base : noncopyable/*XXX todo*/
00058   {
00059     private:
00060       typedef unsigned int algo_serial_type;
00061     public:
00062       struct element_base;
00063 
00064       struct node_base : noncopyable
00065       {
00066           node_base(unifying_partial_ordering_base const* context_)
00067               : algo_serial(0), context(context_) {}
00068           std::set<node_base*> m_sups;
00069           std::set<node_base*> m_infs;
00070           algo_serial_type mutable algo_serial;
00071           union algo_cache_type {
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           link<element_base> users;
00082           unifying_partial_ordering_base const* context; // need algo_serial
00083 
00084           typedef std::set<node_base*>::iterator sup_iterator;
00085           typedef std::set<node_base*>::iterator inf_iterator;
00086       };
00087 
00088       typedef link<element_base>::iterator user_iterator;
00089 
00090       struct element_base : linked
00091       {
00092         protected:
00093           element_base()
00094               : ptr(0) {}
00095           element_base(node_base* p)
00096               : linked(p->users), ptr(p) {}
00097           element_base(element_base const& eb)
00098               : linked(eb.ptr->users), ptr(eb.ptr) {}
00099           element_base& operator=(element_base const& eb) {
00100               unlink();
00101               ptr = eb.ptr;
00102               link_to(ptr->users);
00103               return *this;
00104           }
00105         public:
00106           bool operator==(element_base const& rhs) const {
00107               return ptr == rhs.ptr;
00108           }
00109           bool operator!=(element_base const& rhs) const {
00110               return ptr != rhs.ptr;
00111           }
00112           bool operator<(element_base const& rhs) const {
00113               return ptr < rhs.ptr;
00114           }
00115           //@{
00116           /** not stabilized yet */
00117           void clear_cache() const { ptr->context->clear_cache(); }
00118           void set_cached() const { ptr->set_cached(); }
00119           bool is_cached() const { return ptr->is_cached(); }
00120           node_base::algo_cache_type& cache() const { return ptr->cache(); }
00121           //@}
00122         protected:
00123           mutable node_base* ptr;
00124           friend class unifying_partial_ordering_base;
00125       };
00126 
00127       unifying_partial_ordering_base(node_base* inf, node_base* sup)
00128           : m_min(inf), m_max(sup), algo_serial(0)
00129       {
00130           inf->m_sups.insert(sup);
00131           sup->m_infs.insert(inf);
00132       }
00133 
00134       virtual ~unifying_partial_ordering_base() {}
00135 
00136       void insert_impl(node_base*);
00137       static bool preceq_impl(node_base*, node_base*);
00138     private:
00139       static bool preceq_impl_x(node_base*, node_base*);
00140     public:
00141       static bool eq_impl(node_base* x, node_base* y) { return x == y; }
00142       void constrain_preceq_impl(node_base* x, node_base* y);
00143       void constrain_eq_impl(std::set<node_base*> const& S,
00144                           node_base* new_node);
00145       template<typename OutputIterator>
00146         static bool
00147         copy_range_impl(node_base* x, node_base* y, OutputIterator it)
00148         {
00149             assert(x->context == y->context);
00150             x->context->clear_cache();
00151             return copy_range_impl_x(x, y, it);
00152         }
00153     private:
00154       template<typename OutputIterator>
00155         static bool
00156         copy_range_impl_x(node_base*, node_base*, OutputIterator);
00157     public:
00158       template<typename OutputIterator>
00159         static void
00160         copy_supremums_impl(node_base*, OutputIterator);
00161       template<typename OutputIterator>
00162         static void
00163         copy_infimums_impl(node_base*, OutputIterator);
00164 
00165     protected:
00166       void clear_cache() const;
00167       void check_integrity();
00168       void check_integrity_from_bottom(node_base*);
00169       void check_integrity_from_top(node_base*);
00170       void dump_structure();
00171 
00172       // private:
00173 
00174       node_base* m_min;
00175       node_base* m_max;
00176       algo_serial_type mutable algo_serial;
00177   };
00178 
00179   template<typename T>
00180     struct unify_if_equal
00181         : std::binary_function< T&, T, bool >
00182     {
00183         bool operator()(T& x, T const& y) {
00184             if (x == y)
00185                 return true;
00186             else
00187                 return false;
00188         }
00189     };
00190 
00191   template<typename T>
00192     struct unify_none
00193         : std::binary_function< T&, T, bool >
00194     {
00195         bool operator()(T& x, T const& y)
00196         {
00197             return false;
00198         }
00199     };
00200 
00201   template<typename T>
00202     struct unify_to_first
00203         : std::binary_function< T&, T, bool >
00204     {
00205         bool operator()(T& x, T const& y)
00206         {
00207             return true;
00208         }
00209     };
00210 
00211 
00212 
00213   //
00214   //  -- unifying_partial_ordering --
00215   //
00216 
00217   /** \class unifying_partial_ordering unifying_partial_ordering.h \
00218    **        more/gen/unifying_partial_ordering.h
00219    **
00220    ** A container which provides a partial ordering of its elements. */
00221   template<typename T, typename Unify = unify_if_equal<T> >
00222     struct unifying_partial_ordering : private unifying_partial_ordering_base
00223     {
00224         typedef T value_type;
00225         typedef Unify unify_function;
00226 
00227       private:
00228         struct node : node_base
00229         {
00230             explicit node(unifying_partial_ordering_base const* context_)
00231                 : node_base(context_) {}
00232             node(unifying_partial_ordering_base const* context_, T const& v)
00233                 : node_base(context_), value(v) {}
00234             ~node() {}
00235             T value;
00236         };
00237 
00238       public:
00239         struct const_element;
00240         struct infimum_iterator;
00241         struct const_infimum_iterator;
00242 
00243         /** an element of the ordering */
00244         struct element : element_base
00245         {
00246             typedef unifying_partial_ordering container;
00247             typedef trivial_iterator_tag iterator_category;
00248             typedef void difference_type;
00249             typedef unifying_partial_ordering::infimum_iterator infimum_iterator;
00250             typedef unifying_partial_ordering::infimum_iterator supremum_iterator;
00251             element() {}
00252             element(node_base* p)
00253                 : element_base(p) {}
00254             element(element const& e)
00255                 : element_base(e.ptr) {}
00256 
00257             element& operator=(element const& e)
00258             {
00259                 element_base::operator=(e);
00260                 return *this;
00261             }
00262 
00263             typedef T value_type;
00264             typedef T& reference;
00265             typedef T* pointer;
00266 
00267             reference operator*() { return static_cast<node*>(ptr)->value; }
00268             pointer operator->() { return &static_cast<node*>(ptr)->value; }
00269 
00270             infimum_iterator infimums_begin();
00271             infimum_iterator infimums_end();
00272 
00273             supremum_iterator supremums_begin();
00274             supremum_iterator supremums_end();
00275 
00276           private:
00277             friend class unifying_partial_ordering_base;
00278             friend class unifying_partial_ordering;
00279             friend class const_element;
00280         };
00281 
00282         /** an element of the ordering with constant value */
00283         struct const_element : element_base
00284         {
00285             typedef unifying_partial_ordering container;
00286             typedef trivial_iterator_tag iterator_category;
00287             typedef void difference_type;
00288             typedef unifying_partial_ordering::const_infimum_iterator
00289                     infimum_iterator;
00290             typedef unifying_partial_ordering::const_infimum_iterator
00291                     supremum_iterator;
00292             const_element() {}
00293             const_element(node_base* p)
00294                 : element_base(p) {}
00295             const_element(element const& e)
00296                 : element_base(e.ptr) {}
00297             const_element(const_element const& e)
00298                 : element_base(e.ptr) {}
00299 
00300             const_element& operator=(const_element const& e)
00301             {
00302                 element_base::operator=(e);
00303                 return *this;
00304             }
00305 
00306             typedef T const value_type;
00307             typedef T const& reference;
00308             typedef T const* pointer;
00309 
00310             reference operator*() const
00311             {
00312                 return static_cast<node const*>(ptr)->value;
00313             }
00314 
00315             pointer operator->() const
00316             {
00317                 return &static_cast<node const*>(ptr)->value;
00318             }
00319 
00320             infimum_iterator infimums_begin();
00321             infimum_iterator infimums_end();
00322 
00323             supremum_iterator supremums_begin();
00324             supremum_iterator supremums_end();
00325 
00326           private:
00327             friend class unifying_partial_ordering_base;
00328             friend class unifying_partial_ordering;
00329         };
00330 
00331       private:
00332         // a proxy used in infimum_iterator to emulate const_element
00333         // needed for operator->, and may accelerate operator*.
00334         struct const_proxy0
00335         {
00336             const_proxy0() {}
00337             explicit const_proxy0(node_base::inf_iterator it) : it_sub(it) {}
00338             typedef T const value_type;
00339             typedef T const& reference;
00340             typedef T const* pointer;
00341             reference operator*() const {
00342                 return static_cast<node const*>(*it_sub)->value;
00343             }
00344             pointer operator->() const { return &(operator*()); }
00345             operator const_element() { return *it_sub; }
00346           protected:
00347             node_base::inf_iterator it_sub;
00348         };
00349 
00350         struct proxy0
00351         {
00352             proxy0() {}
00353             explicit proxy0(node_base::inf_iterator it) : it_sub(it) {}
00354             typedef T value_type;
00355             typedef T& reference;
00356             typedef T* pointer;
00357             reference operator*() const {
00358                 return static_cast<node*>(*it_sub)->value;
00359             }
00360             pointer operator->() const { return &(operator*()); }
00361             operator element() { return *it_sub; }
00362           protected:
00363             node_base::inf_iterator it_sub;
00364         };
00365 
00366       public:
00367         /** A bidirectional iterator used by infimum_range. The \c
00368          * operator* (and operator->) returns a proxy which must be
00369          * cast if passed to a templated argument. */
00370         struct infimum_iterator
00371             : private proxy0
00372         {
00373             typedef std::bidirectional_iterator_tag iterator_category;
00374             typedef element value_type;
00375             typedef value_type& reference;
00376             typedef value_type* pointer;
00377             typedef std::ptrdiff_t difference_type;
00378             infimum_iterator() {}
00379             infimum_iterator(node_base::inf_iterator it) : proxy0(it) {}
00380 
00381             proxy0& operator*() { return *this; }
00382             proxy0* operator->() { return this; }
00383 
00384             infimum_iterator& operator++() { ++it_sub; return *this; }
00385             infimum_iterator& operator--() { --it_sub; return *this; }
00386 
00387             infimum_iterator operator++(int)
00388             {
00389                 infimum_iterator tmp = *this;
00390                 ++*this;
00391                 return tmp;
00392             }
00393 
00394             infimum_iterator operator--(int)
00395             {
00396                 infimum_iterator tmp = *this;
00397                 --*this;
00398                 return *this;
00399             }
00400 
00401             bool operator==(infimum_iterator const& rhs) const
00402             {
00403                 return it_sub == rhs.it_sub;
00404             }
00405             bool operator!=(infimum_iterator const& rhs) const
00406             {
00407                 return it_sub != rhs.it_sub;
00408             }
00409         };
00410         /** A bidirectional iterator used by infimum_range. See \c
00411          * infimum_iterator. */
00412         struct const_infimum_iterator
00413             : private const_proxy0
00414         {
00415             typedef std::bidirectional_iterator_tag iterator_category;
00416             typedef const_element value_type;
00417             typedef value_type& reference;
00418             typedef value_type* pointer;
00419             typedef std::ptrdiff_t difference_type;
00420 
00421             const_infimum_iterator() {}
00422             const_infimum_iterator(node_base::inf_iterator it)
00423                 : const_proxy0(it) {}
00424             const_infimum_iterator(infimum_iterator const& it)
00425                 : const_proxy0(it.it_sub) {}
00426 
00427             const_proxy0& operator*() { return *this; }
00428             const_proxy0* operator->() { return this; }
00429 
00430             const_infimum_iterator& operator++() { ++it_sub; return *this; }
00431             const_infimum_iterator& operator--() { --it_sub; return *this; }
00432             const_infimum_iterator operator++(int)
00433             {
00434                 const_infimum_iterator tmp = *this;
00435                 ++*this;
00436                 return tmp;
00437             }
00438             const_infimum_iterator operator--(int)
00439             {
00440                 const_infimum_iterator tmp = *this;
00441                 --*this;
00442                 return *this;
00443             }
00444 
00445             bool operator==(const_infimum_iterator const& rhs) const
00446             {
00447                 return it_sub == rhs.it_sub;
00448             }
00449             bool operator!=(const_infimum_iterator const& rhs) const
00450             {
00451                 return it_sub != rhs.it_sub;
00452             }
00453         };
00454         /** A bidirectional iterator used by supremum_range. */
00455         typedef infimum_iterator supremum_iterator;
00456         /** A bidirectional iterator used by supremum_range. */
00457         typedef const_infimum_iterator const_supremum_iterator;
00458 
00459         /** construct a partial ordering with only infimun and
00460          * supremum elements. */
00461         unifying_partial_ordering()
00462             : unifying_partial_ordering_base(MORE_NEW(node, this),
00463                                     MORE_NEW(node, this)) {}
00464 
00465         /** construct a partial ordering with the given unify function
00466          * object. */
00467         explicit unifying_partial_ordering(unify_function const& fn)
00468             : unifying_partial_ordering_base(MORE_NEW(node, this),
00469                                     MORE_NEW(node, this)),
00470               unify(fn) {}
00471 
00472         /** contruct a deep copy. */
00473         unifying_partial_ordering(unifying_partial_ordering const& po)
00474             : unifying_partial_ordering_base(MORE_NEW(node, this),
00475                                     MORE_NEW(node, this)),
00476               unify(po.unify)
00477         {
00478             insert(po.min(), po.max());
00479             *min() = *po.min();
00480             *max() = *po.max();
00481         }
00482 
00483         /** assign a deep copy. */
00484         unifying_partial_ordering&
00485         operator=(unifying_partial_ordering const& po)
00486         {
00487             clear();
00488             insert(po.min(), po.max());
00489             *min() = *po.min();
00490             *max() = *po.max();
00491             return *this;
00492         }
00493 
00494         /** compare container structure and valued using
00495          * value_type::operator==. */
00496 //      bool operator==(unifying_partial_ordering const& rhs) const {
00497 //          clear_cache();
00498 //          return compare_caching() == 0;
00499 //      }
00500 //      bool operator!=(unifying_partial_ordering const& rhs) const {
00501 //          return !(*this == rhs);
00502 //      }
00503 
00504         /** destructs the partial ordering. All elements created from
00505          * the ordering will be invalidated. */
00506         virtual ~unifying_partial_ordering()
00507         {
00508             clear();
00509             MORE_DELETE(node, static_cast<node*>(m_min));
00510             MORE_DELETE(node, static_cast<node*>(m_max));
00511         }
00512 
00513         /** clear a partial ordering. All elements of the ordering are
00514          * invalidated. */
00515         void clear();
00516 
00517         /** returns true iff \f$e_0\sqsubseteq e_1\f$ is implied by
00518          * the given constraints. */
00519         static bool preceq(element e0, element e1)
00520         {
00521             return preceq_impl(e0.ptr, e1.ptr);
00522         }
00523 
00524         /** returns true iff \f$e_0=e_1\f$ is implied by the given
00525          * contraits. Equivalent to <tt>preceq(e0, e1) && preceq(e1,
00526          * e0)</tt> */
00527         static bool eq(element e0, element e1)
00528         {
00529             return eq_impl(e0.ptr, e1.ptr);
00530         }
00531 
00532         /** imposes the constraint \f$e_0\sqsubseteq e_1\f$. */
00533         bool constrain_preceq(element e0, element e1);
00534 
00535         /** imposes the constraint \f$e_0=e_1\f$. Equivalent to
00536          * <tt>constrain_preceq(e0, e1), constrain_preceq(e1, e0)</tt>. */
00537         bool constrain_eq(element e0, element e1);
00538       private:
00539         bool constrain_eq(std::set<node_base*> const&);
00540         static node_base* copy_caching(node_base*, node_base*, node_base*);
00541 //      static int compare_caching(node_base*, node_base*, node_base*);
00542 
00543       public:
00544         /** create a new element with the given value. */
00545         element insert(T const& value)
00546         {
00547             node* ptr = MORE_NEW(node, this, value);
00548             insert_impl(ptr);
00549             return ptr;
00550         }
00551 
00552         /** create a new default constructed element. */
00553         element insert()
00554         {
00555             node* ptr = MORE_NEW(node, this);
00556             insert_impl(ptr);
00557             return ptr;
00558         }
00559 
00560         /** insert a range of values. Equivalent to <tt>insert(e_min,
00561          * e_max, min(), max())</tt>. */
00562         void insert(const_element e_min, const_element e_max)
00563         {
00564             insert(e_min, e_max, min(), max());
00565         }
00566 
00567         /** insert nodes in (e_min, e_max) into (e_min_dest,
00568          * e_max_dest). */
00569         void insert(const_element e_min, const_element e_max,
00570                     element e_min_dest, element e_max_dest)
00571         {
00572             if (e_min == e_max) return;
00573             if (e_min_dest == e_max_dest)
00574                 throw std::logic_error(
00575                     "more::gen::unifying_partial_ordering::insert: "
00576                     "Invalid destination range.");
00577             e_min.clear_cache();
00578             for (node_base::sup_iterator it = e_min.ptr->m_sups.begin();
00579                  it != e_min.ptr->m_sups.end(); ++it)
00580             {
00581                 node_base* node_new
00582                     = copy_caching(*it, e_max.ptr, e_max_dest.ptr);
00583                 e_min_dest.ptr->m_sups.insert(node_new);
00584                 node_new->m_infs.insert(e_min_dest.ptr);
00585             }
00586         }
00587 
00588         /** returns the element which is less than any other
00589          * element. It is dereferenceable. */
00590         const_element min() const { return m_min; }
00591 
00592         /** returns the element which is greater than any other
00593          * element. It is derferenceable. */
00594         const_element max() const { return m_max; }
00595 
00596         /** returns the element which is less than any other element.
00597          * It is dereferenceable with an lvalue as the result. */
00598         element min() { return m_min; }
00599 
00600         /** returns the element which is greater than any other element.
00601          * It is dereferenceable with an lvalue as the result. */
00602         element max() { return m_max; }
00603 
00604         template<typename OutputIterator>
00605           static void copy_range(element, element, OutputIterator);
00606         template<typename OutputIterator>
00607           static void copy_range(const_element, const_element,
00608                                  OutputIterator);
00609         template<typename OutputIterator>
00610           static void copy_supremums(element, OutputIterator);
00611         template<typename OutputIterator>
00612           static void copy_supremums(const_element, OutputIterator);
00613         template<typename OutputIterator>
00614           static void copy_infimums(element, OutputIterator);
00615         template<typename OutputIterator>
00616           static void copy_infimums(const_element, OutputIterator);
00617 //      template<typename PrecEqPredicate, typename OutputIterator>
00618 //        static void copy_infimums(value_type const&, PrecEqPredicate,
00619 //                                  OutputIterator);
00620 
00621         /** Returns a range of the infimums of \c x. Note that the
00622          * value_type of the iterator is \c const_element, so a double
00623          * dereference is needed to obtain a \c value_type of this
00624          * container. */
00625         static std::pair<const_infimum_iterator, const_infimum_iterator>
00626         infimum_range(const_element x)
00627         {
00628             return std::make_pair(const_infimum_iterator(x.ptr->m_infs.begin()),
00629                                   const_infimum_iterator(x.ptr->m_infs.end()));
00630         }
00631 
00632         /** Returns a range of the supremums of \c x. See \c
00633          * infimum_range(const_element)  const. */
00634         static std::pair<const_supremum_iterator, const_supremum_iterator>
00635         supremum_range(const_element x)
00636         {
00637             return std::make_pair(const_supremum_iterator(x.ptr->m_sups.begin()),
00638                                   const_supremum_iterator(x.ptr->m_sups.end()));
00639         }
00640 
00641         /** Returns a range of the infimums of \c x. See \c
00642          * infimum_range(const_element) const. */
00643         static std::pair<infimum_iterator, infimum_iterator>
00644         infimum_range(element x)
00645         {
00646             return std::make_pair(infimum_iterator(x.ptr->m_infs.begin()),
00647                                   infimum_iterator(x.ptr->m_infs.end()));
00648         }
00649 
00650         /** Returns a range of the supremums of \c x. See \c
00651          * infimum_range(const_element) const. */
00652         static std::pair<supremum_iterator, supremum_iterator>
00653         supremum_range(element x) {
00654             return std::make_pair(supremum_iterator(x.ptr->m_sups.begin()),
00655                                   supremum_iterator(x.ptr->m_sups.end()));
00656         }
00657 
00658       private:
00659         unify_function unify;
00660     };
00661 
00662   template<typename T, typename Unify>
00663     inline typename
00664     unifying_partial_ordering<T, Unify>::element::supremum_iterator
00665     unifying_partial_ordering<T, Unify>::element::supremums_begin()
00666     {
00667         return ptr->m_sups.begin();
00668     }
00669   template<typename T, typename Unify>
00670     inline typename
00671     unifying_partial_ordering<T, Unify>::element::supremum_iterator
00672     unifying_partial_ordering<T, Unify>::element::supremums_end()
00673     {
00674         return ptr->m_sups.end();
00675     }
00676 
00677   template<typename T, typename Unify>
00678     inline typename
00679     unifying_partial_ordering<T, Unify>::element::infimum_iterator
00680     unifying_partial_ordering<T, Unify>::element::infimums_begin()
00681     {
00682         return ptr->m_infs.begin();
00683     }
00684   template<typename T, typename Unify>
00685     inline typename
00686     unifying_partial_ordering<T, Unify>::element::infimum_iterator
00687     unifying_partial_ordering<T, Unify>::element::infimums_end()
00688     {
00689         return ptr->m_infs.end();
00690     }
00691 
00692   template<typename T, typename Unify>
00693     inline typename
00694     unifying_partial_ordering<T, Unify>::const_element::supremum_iterator
00695     unifying_partial_ordering<T, Unify>::const_element::supremums_begin()
00696     {
00697         return ptr->m_sups.begin();
00698     }
00699   template<typename T, typename Unify>
00700     inline typename
00701     unifying_partial_ordering<T, Unify>::const_element::supremum_iterator
00702     unifying_partial_ordering<T, Unify>::const_element::supremums_end()
00703     {
00704         return ptr->m_sups.end();
00705     }
00706 
00707   template<typename T, typename Unify>
00708     inline typename
00709     unifying_partial_ordering<T, Unify>::const_element::infimum_iterator
00710     unifying_partial_ordering<T, Unify>::const_element::infimums_begin()
00711     {
00712         return ptr->m_infs.begin();
00713     }
00714   template<typename T, typename Unify>
00715     inline typename
00716     unifying_partial_ordering<T, Unify>::const_element::infimum_iterator
00717     unifying_partial_ordering<T, Unify>::const_element::infimums_end()
00718     {
00719         return ptr->m_infs.end();
00720     }
00721 
00722   template<typename Element>
00723     std::pair< typename Element::supremum_iterator,
00724                typename Element::supremum_iterator >
00725     supremums(Element e)
00726     {
00727         return std::make_pair(e.supremums_begin(),
00728                               e.supremums_end());
00729     }
00730   template<typename Element>
00731     std::pair< typename Element::infimum_iterator,
00732                typename Element::infimum_iterator >
00733     infimums(Element e)
00734     {
00735         return std::make_pair(e.infimums_begin(),
00736                               e.infimums_end());
00737     }
00738 
00739   /** returns true if \f$e_0\sqsubseteq e_1\f$. */
00740   template<typename Element>
00741     inline bool preceq(Element e0, Element e1)
00742     {
00743         typedef typename Element::container container;
00744         return container::preceq(e0, e1);
00745     }
00746 
00747   /** returns true if \f$e_0\sqsubset e_1\f$. */
00748   template<typename Element>
00749     inline bool prec(Element e0, Element e1)
00750     {
00751         return e0 != e1 && preceq(e0, e1);
00752     }
00753 
00754   /** returns true if \f$e_0\sqsupseteq e_1\f$. */
00755   template<typename Element>
00756     inline bool succeq(Element e0, Element e1) { return preceq(e1, e0); }
00757 
00758   /** returns true if \f$e_0\sqsupset e_1\f$. */
00759   template<typename Element>
00760     inline bool succ(Element e0, Element e1) { return prec(e1, e0); }
00761 
00762 ///\if bits
00763 }
00764   using bits_upo::unifying_partial_ordering;
00765   using bits_upo::unify_to_first;
00766   using bits_upo::unify_if_equal;
00767   using bits_upo::unify_none;
00768 ///\endif
00769 
00770   // The rest is Koenig lookup.
00771 }} // more::gen
00772 
00773 #include <more/bits/unifying_partial_ordering.tcc>
00774 
00775 #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.