Milena (Olena)
User documentation 2.0a Id
|
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