Milena (Olena)  User documentation 2.0a Id
height.hh
00001 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
00002 // Laboratory (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_MORPHO_ATTRIBUTE_HEIGHT_HH
00028 # define MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
00029 
00033 
00034 # include <mln/accu/internal/base.hh>
00035 
00036 # include <mln/util/pix.hh>
00037 # include <mln/math/diff_abs.hh>
00038 # include <mln/math/min.hh>
00039 # include <mln/math/max.hh>
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   // Forward declaration.
00046   namespace morpho {
00047     namespace attribute {
00048       template <typename I> struct height;
00049     }
00050   }
00051 
00052 
00053   // Traits.
00054 
00055   namespace trait
00056   {
00057 
00058     template <typename I>
00059     struct accumulator_< morpho::attribute::height<I> >
00060     {
00061       typedef accumulator::has_untake::no    has_untake;
00062       typedef accumulator::has_set_value::no has_set_value;
00063       typedef accumulator::has_stop::no      has_stop;
00064       typedef accumulator::when_pix::use_v   when_pix;
00065     };
00066 
00067   } // end of namespace mln::trait
00068 
00069 
00070   namespace morpho
00071   {
00072 
00073     namespace attribute
00074     {
00075 
00080       template <typename I>
00081       struct height
00082         : public mln::accu::internal::base< unsigned , height<I> >
00083       {
00084         typedef mln_value(I) argument;
00085 
00086         height();
00087 
00090         void init();
00091         void take(const mln_value(I)& v);
00092         void take(const util::pix<I>& v);
00093         void take(const height<I>& other);
00094         void take_as_init_(const mln_value(I)& v);
00095         void take_as_init_(const util::pix<I>& px);
00097 
00100         bool is_valid() const;
00101 
00103         unsigned to_result() const;
00104 
00106         unsigned base_level() const;
00107         unsigned current_level() const;
00108 
00109 
00110       protected:
00112         unsigned ref_;
00114         unsigned cur_;
00116         bool initialized_;
00117       };
00118 
00119 
00120 # ifndef MLN_INCLUDE_ONLY
00121 
00122       template <typename I>
00123       inline
00124       height<I>::height()
00125         : initialized_ (false)
00126       {
00127       }
00128 
00129       template <typename I>
00130       inline
00131       void
00132       height<I>::init()
00133       {
00134         mln_invariant(0);
00135       }
00136 
00137       template <typename I>
00138       inline
00139       void
00140       height<I>::take(const mln_value(I)& v)
00141       {
00142         if (!is_valid ())
00143           {
00144             take_as_init_(v);
00145           }
00146         cur_ = v;
00147       }
00148 
00149       template <typename I>
00150       inline
00151       void
00152       height<I>::take(const util::pix<I>& px)
00153       {
00154         take(px.v());
00155       }
00156 
00157       template <typename I>
00158       inline
00159       void
00160       height<I>::take(const height<I>& other)
00161       {
00162         mln_invariant(((ref_ <= cur_) && (other.ref_ <= other.cur_))
00163                       || ((ref_ >= cur_) && (other.ref_ >= other.cur_)));
00164 
00165         if (!is_valid())
00166           {
00167             ref_ = other.ref_;
00168             cur_ = other.cur_;
00169           }
00170         else if (ref_ < cur_)
00171           {
00172             // Values are increasing.
00173             ref_ = math::min(ref_, other.ref_);
00174             cur_ = math::max(cur_, other.cur_);
00175           }
00176         else
00177           {
00178             // Values are decreasing.
00179             ref_ = math::max(ref_, other.ref_);
00180             cur_ = math::min(cur_, other.cur_);
00181           }
00182       }
00183 
00184       template <typename I>
00185       inline
00186       void
00187       height<I>::take_as_init_(const mln_value(I)& v)
00188       {
00189         cur_ = ref_ = v;
00190         initialized_ = true;
00191       }
00192 
00193       template <typename I>
00194       inline
00195       void
00196       height<I>::take_as_init_(const util::pix<I>& px)
00197       {
00198         take_as_init_(px.v());
00199       }
00200 
00201 
00202       template <typename I>
00203       inline
00204       unsigned
00205       height<I>::to_result() const
00206       {
00207         mln_invariant(is_valid());
00208 
00209         return math::diff_abs(ref_, cur_);
00210       }
00211 
00212       template <typename I>
00213       inline
00214       unsigned
00215       height<I>::base_level() const
00216       {
00217         return ref_;
00218       }
00219 
00220       template <typename I>
00221       inline
00222       unsigned
00223       height<I>::current_level() const
00224       {
00225         return cur_;
00226       }
00227 
00228 
00229       template <typename I>
00230       inline
00231       bool
00232       height<I>::is_valid() const
00233       {
00234         return initialized_;
00235       }
00236 
00237 # endif // ! MLN_INCLUDE_ONLY
00238 
00239     } // end of namespace mln::morpho::attribute
00240 
00241   } // end of namespace mln::morpho
00242 
00243 } // end of namespace mln
00244 
00245 
00246 #endif // ! MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator