00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
00027 # define MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
00028
00032
00033 # include <mln/accu/internal/base.hh>
00034
00035 # include <mln/util/pix.hh>
00036 # include <mln/math/diff_abs.hh>
00037 # include <mln/math/min.hh>
00038 # include <mln/math/max.hh>
00039
00040
00041 namespace mln
00042 {
00043
00044
00045 namespace morpho {
00046 namespace attribute {
00047 template <typename I> class height;
00048 }
00049 }
00050
00051
00052
00053
00054 namespace trait
00055 {
00056
00057 template <typename I>
00058 struct accumulator_< morpho::attribute::height<I> >
00059 {
00060 typedef accumulator::has_untake::no has_untake;
00061 typedef accumulator::has_set_value::no has_set_value;
00062 typedef accumulator::has_stop::no has_stop;
00063 typedef accumulator::when_pix::use_v when_pix;
00064 };
00065
00066 }
00067
00068
00069 namespace morpho
00070 {
00071
00072 namespace attribute
00073 {
00074
00079 template <typename I>
00080 struct height
00081 : public mln::accu::internal::base< unsigned , height<I> >
00082 {
00083 typedef mln_value(I) argument;
00084
00085 height();
00086
00089 void init();
00090 void take(const mln_value(I)& v);
00091 void take(const util::pix<I>& v);
00092 void take(const height<I>& other);
00093 void take_as_init_(const mln_value(I)& v);
00094 void take_as_init_(const util::pix<I>& px);
00096
00099 bool is_valid() const;
00100
00102 unsigned to_result() const;
00103
00105 unsigned base_level() const;
00106 unsigned current_level() const;
00107
00108
00109 protected:
00111 unsigned ref_;
00113 unsigned cur_;
00115 bool initialized_;
00116 };
00117
00118
00119 # ifndef MLN_INCLUDE_ONLY
00120
00121 template <typename I>
00122 inline
00123 height<I>::height()
00124 : initialized_ (false)
00125 {
00126 }
00127
00128 template <typename I>
00129 inline
00130 void
00131 height<I>::init()
00132 {
00133 mln_invariant(0);
00134 }
00135
00136 template <typename I>
00137 inline
00138 void
00139 height<I>::take(const mln_value(I)& v)
00140 {
00141 if (!is_valid ())
00142 {
00143 take_as_init_(v);
00144 }
00145 cur_ = v;
00146 }
00147
00148 template <typename I>
00149 inline
00150 void
00151 height<I>::take(const util::pix<I>& px)
00152 {
00153 take(px.v());
00154 }
00155
00156 template <typename I>
00157 inline
00158 void
00159 height<I>::take(const height<I>& other)
00160 {
00161 mln_invariant(((ref_ <= cur_) && (other.ref_ <= other.cur_))
00162 || ((ref_ >= cur_) && (other.ref_ >= other.cur_)));
00163
00164 if (!is_valid())
00165 {
00166 ref_ = other.ref_;
00167 cur_ = other.cur_;
00168 }
00169 else if (ref_ < cur_)
00170 {
00171
00172 ref_ = math::min(ref_, other.ref_);
00173 cur_ = math::max(cur_, other.cur_);
00174 }
00175 else
00176 {
00177
00178 ref_ = math::max(ref_, other.ref_);
00179 cur_ = math::min(cur_, other.cur_);
00180 }
00181 }
00182
00183 template <typename I>
00184 inline
00185 void
00186 height<I>::take_as_init_(const mln_value(I)& v)
00187 {
00188 cur_ = ref_ = v;
00189 initialized_ = true;
00190 }
00191
00192 template <typename I>
00193 inline
00194 void
00195 height<I>::take_as_init_(const util::pix<I>& px)
00196 {
00197 take_as_init_(px.v());
00198 }
00199
00200
00201 template <typename I>
00202 inline
00203 unsigned
00204 height<I>::to_result() const
00205 {
00206 mln_invariant(is_valid());
00207
00208 return math::diff_abs(ref_, cur_);
00209 }
00210
00211 template <typename I>
00212 inline
00213 unsigned
00214 height<I>::base_level() const
00215 {
00216 return ref_;
00217 }
00218
00219 template <typename I>
00220 inline
00221 unsigned
00222 height<I>::current_level() const
00223 {
00224 return cur_;
00225 }
00226
00227
00228 template <typename I>
00229 inline
00230 bool
00231 height<I>::is_valid() const
00232 {
00233 return initialized_;
00234 }
00235
00236 # endif // ! MLN_INCLUDE_ONLY
00237
00238 }
00239
00240 }
00241
00242 }
00243
00244
00245 #endif // ! MLN_MORPHO_ATTRIBUTE_HEIGHT_HH