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
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
00046 namespace morpho {
00047 namespace attribute {
00048 template <typename I> struct height;
00049 }
00050 }
00051
00052
00053
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 }
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
00173 ref_ = math::min(ref_, other.ref_);
00174 cur_ = math::max(cur_, other.cur_);
00175 }
00176 else
00177 {
00178
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 }
00240
00241 }
00242
00243 }
00244
00245
00246 #endif // ! MLN_MORPHO_ATTRIBUTE_HEIGHT_HH