Milena (Olena)  User documentation 2.0a Id
object_id.hh
00001 // Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
00002 // (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena 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 GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project 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 produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_UTIL_OBJECT_ID_HH
00028 # define MLN_UTIL_OBJECT_ID_HH
00029 
00033 
00034 
00035 # include <mln/core/concept/object.hh>
00036 # include <mln/value/concept/integer.hh>
00037 # include <mln/metal/abort.hh>
00038 
00039 namespace mln
00040 {
00041 
00042     // Forward declaration
00043   namespace util { template <typename Tag, typename V> class object_id; }
00044 
00045   namespace convert
00046   {
00047 
00048     namespace over_load
00049     {
00050 
00051       // object_id<Tag,V> -> V.
00052       template <typename Tag, typename V>
00053       void from_to_(const util::object_id<Tag,V>& from, V& to_);
00054 
00055     } // end of namespace mln::convert::over_load
00056 
00057   } // end of namespace mln::convert
00058 
00059 
00060   namespace util
00061   {
00062 
00066     template <typename Tag, typename V>
00067     class object_id : public value::Integer< object_id<Tag, V> >
00068     {
00069       public:
00071         typedef V value_t;
00072         typedef unsigned equiv;
00073         typedef V enc;
00074 
00077         object_id();
00078 
00079         template <typename V2>
00080           object_id(const V2& id);
00081 
00082         template <typename Tag2, typename V2>
00083           object_id(const object_id<Tag2,V2>& other);
00085 
00086         template <typename V2>
00087           object_id<Tag,V>& operator=(const V2& e);
00088 
00089         const V& value() const;
00090         V& value();
00091 
00092         operator unsigned() const;
00093 
00094         bool is_valid() const;
00095         void invalidate();
00096 
00097         unsigned to_equiv() const;
00098 
00099       protected:
00100         V id_;
00101     };
00102 
00103 
00104     template <typename Tag, typename V>
00105     bool
00106     operator==(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs);
00107 
00108     template <typename Tag, typename V, typename V2>
00109     bool
00110     operator<(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs);
00111 
00112   } // end of namespace mln::util
00113 
00114 # ifndef MLN_INCLUDE_ONLY
00115 
00116   namespace util
00117   {
00118 
00119     template <typename Tag, typename V>
00120     inline
00121     object_id<Tag,V>::object_id()
00122     : id_(mln_max(V))
00123     {
00124     }
00125 
00126     template <typename Tag, typename V>
00127     template <typename V2>
00128     inline
00129     object_id<Tag,V>::object_id(const V2& id)
00130       : id_(id)
00131     {
00132       mlc_converts_to(V2,V)::check();
00133     }
00134 
00135     template <typename Tag, typename V>
00136     template <typename Tag2, typename V2>
00137     inline
00138     object_id<Tag,V>::object_id(const object_id<Tag2,V2>& id)
00139     {
00140       (void) id;
00141       typedef object_id<Tag2,V2> id_t;
00142       mlc_abort(id_t)::check();
00143     }
00144 
00145     template <typename Tag, typename V>
00146     template <typename V2>
00147     inline
00148     object_id<Tag,V>&
00149     object_id<Tag,V>::operator=(const V2& v)
00150     {
00151       mlc_converts_to(V2,V)::check();
00152 
00153       id_ = v;
00154       return *this;
00155     }
00156 
00157     template <typename Tag, typename V>
00158     inline
00159     V&
00160     object_id<Tag,V>::value()
00161     {
00162       return id_;
00163     }
00164 
00165     template <typename Tag, typename V>
00166     inline
00167     const V&
00168     object_id<Tag,V>::value() const
00169     {
00170       return id_;
00171     }
00172 
00173     template <typename Tag, typename V>
00174     inline
00175     object_id<Tag,V>::operator unsigned() const
00176     {
00177       return id_;
00178     }
00179 
00180 
00181     template <typename Tag, typename V>
00182     inline
00183     bool
00184     object_id<Tag,V>::is_valid() const
00185     {
00186       return id_ != mln_max(V);
00187     }
00188 
00189     template <typename Tag, typename V>
00190     inline
00191     void
00192     object_id<Tag,V>::invalidate()
00193     {
00194       id_ = mln_max(V);
00195     }
00196 
00197     template <typename Tag, typename V>
00198     inline
00199     unsigned
00200     object_id<Tag,V>::to_equiv() const
00201     {
00202       return id_;
00203     }
00204 
00205 
00206 
00207     template <typename Tag, typename V, typename V2>
00208     inline
00209     bool
00210     operator==(const object_id<Tag,V>& lhs, const Value<V2>& rhs)
00211     {
00212       return lhs.value() == exact(rhs).to_equiv();
00213     }
00214 
00215     template <typename Tag, typename V>
00216     inline
00217     bool
00218     operator==(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs)
00219     {
00220       return lhs.value() == rhs.value();
00221     }
00222 
00223     template <typename Tag, typename V>
00224     inline
00225     bool
00226     operator<(const object_id<Tag,V>& lhs, const object_id<Tag,V>& rhs)
00227     {
00228       return lhs.value() < rhs.value();
00229     }
00230 
00231   } // end of namespace mln::util
00232 
00233   namespace convert
00234   {
00235 
00236     namespace over_load
00237     {
00238 
00239       // object_id<Tag,V> -> V.
00240       template <typename Tag, typename V>
00241       void from_to_(const util::object_id<Tag,V>& from, V& to_)
00242       {
00243         to_ = from.value();
00244       }
00245 
00246     } // end of namespace mln::convert::over_load
00247 
00248   } // end of namespace mln::convert
00249 
00250 # endif // ! MLN_INCLUDE_ONLY
00251 
00252 } // end of namespace mln
00253 
00254 #endif // ! MLN_UTIL_OBJECT_ID_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator