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
00028
00029
00030 #ifndef MORE_GEN_PO_ALGO_H
00031 #define MORE_GEN_PO_ALGO_H
00032
00033
00034 namespace more {
00035 namespace gen {
00036
00037
00038 template<typename Element>
00039 inline bool
00040 is_max_element(Element e)
00041 {
00042 return e.supremums_begin() == e.supremums_end();
00043 }
00044
00045
00046 template<typename Element>
00047 inline bool
00048 is_min_element(Element e)
00049 {
00050 return e.infimums_begin() == e.infimums_end();
00051 }
00052
00053
00054
00055
00056
00057
00058 template<typename Element, typename OutputIterator>
00059 bool
00060 _copy_open_range(Element e_low, Element e_high, OutputIterator it_out)
00061 {
00062 if (e_low.is_cached())
00063 return e_low.cache().as_bool;
00064 e_low.set_cached();
00065 bool is_reachable = false;
00066 for (typename Element::supremum_iterator it = e_low.supremums_begin();
00067 it != e_low.supremums_end(); ++it) {
00068 if (*it == e_high)
00069 is_reachable = true;
00070 else if (_copy_open_range((Element)*it, e_high, it_out)) {
00071 is_reachable = true;
00072 *it_out = *it, ++it_out;
00073 }
00074 }
00075 return e_low.cache().as_bool = is_reachable;
00076 }
00077
00078
00079
00080 template<typename Element, typename OutputIterator>
00081 bool
00082 copy_open_range(Element e_low, Element e_high, OutputIterator it_out)
00083 {
00084 check_range(e_low, e_high);
00085 e_low.clear_cache();
00086 return e_low == e_high || _copy_open_range(e_low, e_high, it_out);
00087 }
00088
00089
00090 template<typename Element, typename OutputIterator>
00091 bool
00092 copy_closed_range(Element e_low, Element e_high, OutputIterator it_out)
00093 {
00094 if (e_low == e_high) {
00095 *it_out = e_low, ++it_out;
00096 return true;
00097 }
00098 check_range(e_low, e_high);
00099 e_low.clear_cache();
00100 if (_copy_open_range(e_low, e_high, it_out)) {
00101 *it_out = e_low, ++it_out;
00102 *it_out = e_high, ++it_out;
00103 return true;
00104 }
00105 return false;
00106 }
00107
00108
00109 template<typename Element, typename OutputIterator>
00110 bool
00111 copy_left_range(Element e_low, Element e_high, OutputIterator it_out)
00112 {
00113 if (e_low == e_high) return true;
00114 check_range(e_low, e_high);
00115 e_low.clear_cache();
00116 if (_copy_open_range(e_low, e_high, it_out)) {
00117 *it_out = e_low, ++it_out;
00118 return true;
00119 }
00120 return false;
00121 }
00122
00123
00124 template<typename Element, typename OutputIterator>
00125 bool
00126 copy_right_range(Element e_low, Element e_high, OutputIterator it_out)
00127 {
00128 if (e_low == e_high) return true;
00129 check_range(e_low, e_high);
00130 e_low.clear_cache();
00131 if (_copy_open_range(e_low, e_high, it_out)) {
00132 *it_out = e_high, ++it_out;
00133 return true;
00134 }
00135 return false;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145 template<typename Element, typename Predicate, typename OutputIterator>
00146 bool
00147 _find_infimums(Element e_low,
00148 Predicate pred, OutputIterator it_out)
00149 {
00150 if (e_low.is_cached())
00151 return e_low.cache().as_bool;
00152 e_low.set_cached();
00153 if (is_max_element(e_low)
00154 || !is_min_element(e_low) && !pred(*e_low))
00155 return e_low.cache().as_bool = false;
00156 bool found = false;
00157 for (typename Element::supremum_iterator
00158 it_sup = e_low.supremums_begin();
00159 it_sup != e_low.supremums_end(); ++it_sup) {
00160 if (_find_infimums(Element(*it_sup), pred,
00161 it_out))
00162 found = true;
00163 }
00164 if (!found)
00165 *it_out = e_low, ++it_out;
00166 return e_low.cache().as_bool = true;
00167 }
00168
00169 template<typename Element, typename Predicate, typename OutputIterator>
00170 bool
00171 _find_supremums(Element e_high,
00172 Predicate pred, OutputIterator it_out)
00173 {
00174 if (e_high.is_cached())
00175 return e_high.cache().as_bool;
00176 e_high.set_cached();
00177 if (is_min_element(e_high)
00178 || !is_max_element(e_high) && !pred(*e_high))
00179 return e_high.cache().as_bool = false;
00180 bool found = false;
00181 for (typename Element::infimum_iterator
00182 it_inf = e_high.infimums_begin();
00183 it_inf != e_high.infimums_end(); ++it_inf) {
00184 if (_find_supremums(Element(*it_inf), pred,
00185 it_out))
00186 found = true;
00187 }
00188 if (!found)
00189 *it_out = e_high, ++it_out;
00190 return e_high.cache().as_bool = true;
00191 }
00192
00193
00194
00195
00196 template< typename Element, typename Value, typename PrecEqPredicate,
00197 typename OutputIterator >
00198 void
00199 find_infimums(Element e_low, Value const& value,
00200 PrecEqPredicate preceq, OutputIterator it_out)
00201 {
00202 e_low.clear_cache();
00203 _find_infimums(e_low, std::bind2nd(preceq, value), it_out);
00204 }
00205
00206
00207
00208 template< typename Element, typename Value, typename PrecEqPredicate,
00209 typename OutputIterator >
00210 void
00211 find_infimums_above(Element e_low, Value const& value,
00212 PrecEqPredicate preceq, OutputIterator it_out)
00213 {
00214 e_low.clear_cache();
00215 for (typename Element::supremum_iterator it
00216 = e_low.supremums_begin(); it != e_low.supremums_end(); ++it)
00217 _find_infimums(Element(*it), std::bind2nd(preceq, value), it_out);
00218 }
00219
00220
00221
00222 template< typename Element, typename Value, typename PrecEqPredicate,
00223 typename OutputIterator >
00224 void
00225 find_supremums(Element e_high, Value const& value,
00226 PrecEqPredicate preceq, OutputIterator it_out)
00227 {
00228 e_high.clear_cache();
00229 _find_supremums(e_high, std::bind1st(preceq, value), it_out);
00230 }
00231
00232
00233
00234 template< typename Element, typename Value, typename PrecEqPredicate,
00235 typename OutputIterator >
00236 void
00237 find_supremums_below(Element e_high, Value const& value,
00238 PrecEqPredicate preceq, OutputIterator it_out)
00239 {
00240 e_high.clear_cache();
00241 for (typename Element::infimum_iterator it
00242 = e_high.infimums_begin(); it != e_high.infimums_end(); ++it)
00243 _find_supremums(Element(*it), std::bind1st(preceq, value), it_out);
00244 }
00245
00246
00247
00248 template<typename Element, typename Predicate, typename OutputIterator>
00249 void
00250 find_infimums_if(Element e_low, Predicate const& pred,
00251 OutputIterator it_out)
00252 {
00253 e_low.clear_cache();
00254 _find_infimums(e_low, pred, it_out);
00255 }
00256
00257 template<typename Element, typename Predicate, typename OutputIterator>
00258 void
00259 find_supremums_if(Element e_high, Predicate const& pred,
00260 OutputIterator it_out)
00261 {
00262 e_high.clear_cache();
00263 _find_supremums(e_high, pred, it_out);
00264 }
00265
00266
00267 template<typename Element, typename Predicate, typename OutputIterator>
00268 void
00269 find_infimums_above_if(Element e_low, Predicate const& pred,
00270 OutputIterator it_out)
00271 {
00272 e_low.clear_cache();
00273 for (typename Element::supremum_iterator it
00274 = e_low.supremums_begin(); it != e_low.supremums_end(); ++it)
00275 _find_infimums(Element(*it), pred, it_out);
00276 }
00277
00278 template<typename Element, typename Predicate, typename OutputIterator>
00279 void
00280 find_supremums_below_if(Element e_high, Predicate const& pred,
00281 OutputIterator it_out)
00282 {
00283 e_high.clear_cache();
00284 for (typename Element::infimum_iterator it
00285 = e_high.infimums_begin(); it != e_high.infimums_end(); ++it)
00286 _find_supremums(Element(*it), pred, it_out);
00287 }
00288
00289 }}
00290
00291 #endif