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