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_FUN_V2V_SATURATE_HH
00028 # define MLN_FUN_V2V_SATURATE_HH
00029
00035 # include <mln/core/concept/function.hh>
00036 # include <mln/metal/converts_to.hh>
00037 # include <mln/trait/value_.hh>
00038 # include <mln/value/cast.hh>
00039 # include <mln/convert/from_to.hh>
00040
00041
00042 namespace mln
00043 {
00044
00045 namespace fun
00046 {
00047
00048 namespace v2v
00049 {
00050
00051
00052
00053 template <typename V>
00054 struct saturate : public Function_v2v< saturate<V> >
00055 {
00056 saturate();
00057 saturate(const V& min, const V& max);
00058
00059 typedef V result;
00060
00061 template <typename W>
00062 V operator()(const W& w) const;
00063
00064 protected:
00065 V min_, max_;
00066 mutable bool needs_update_;
00067 };
00068
00069
00070 # ifndef MLN_INCLUDE_ONLY
00071
00072 template <typename V>
00073 inline
00074 saturate<V>::saturate()
00075 : min_(mln_min(V)),
00076 max_(mln_max(V))
00077 {
00078 needs_update_ = true;
00079 }
00080
00081 template <typename V>
00082 inline
00083 saturate<V>::saturate(const V& min, const V& max)
00084 : min_(min),
00085 max_(max)
00086 {
00087 mln_precondition(max > min);
00088 needs_update_ = true;
00089 }
00090
00091 template <typename V>
00092 template <typename W>
00093 inline
00094 V
00095 saturate<V>::operator()(const W& w) const
00096 {
00097
00098
00099
00100 static W min_W, max_W;
00101 if (needs_update_)
00102 {
00103 min_W = mln::value::cast<W>(min_);
00104 max_W = mln::value::cast<W>(max_);
00105 needs_update_ = false;
00106 }
00107
00108
00109
00110
00111
00112
00113 if (w < min_W)
00114 return min_;
00115 if (w > max_W)
00116 return max_;
00117
00118 V output;
00119 mln::convert::from_to(w, output);
00120 return output;
00121 }
00122
00123 # endif // ! MLN_INCLUDE_ONLY
00124
00125 }
00126
00127 }
00128
00129 }
00130
00131
00132 #endif // ! MLN_FUN_V2V_SATURATE_HH