BWAPI
|
00001 // Copyright (c) 2001-2005 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Filtered_kernel/include/CGAL/Filtered_predicate.h $ 00016 // $Id: Filtered_predicate.h 46443 2008-10-23 13:01:01Z afabri $ 00017 // 00018 // 00019 // Author(s) : Sylvain Pion 00020 00021 #ifndef CGAL_FILTERED_PREDICATE_H 00022 #define CGAL_FILTERED_PREDICATE_H 00023 00024 #include <string> 00025 #include <CGAL/config.h> 00026 #include <CGAL/Interval_nt.h> 00027 #include <CGAL/Uncertain.h> 00028 #include <CGAL/Profile_counter.h> 00029 00030 CGAL_BEGIN_NAMESPACE 00031 00032 // This template class is a wrapper that implements the filtering for any 00033 // predicate (dynamic filters with IA). 00034 00035 // TODO : 00036 // - each predicate in the default kernel should define a tag that says if it 00037 // wants to be filtered or not (=> all homogeneous predicate define this 00038 // tag). We could even test-suite that automatically. It makes a strong 00039 // new requirement on the kernel though... 00040 // Could be done with a traits mecanism ? 00041 // A default template could use the current IA, but other tags or whatever 00042 // could specify no filtering at all, or static filtering... 00043 // - same thing for constructions => virtual operator() ? 00044 // - similarly, constructions should have a tag saying if they can throw or 00045 // not, or we let all this up to the compiler optimizer to figure out ? 00046 // - Some caching could be done at the Point_2 level. 00047 00048 00049 template <class EP, class AP, class C2E, class C2A, bool Protection = true> 00050 class Filtered_predicate 00051 { 00052 EP ep; 00053 AP ap; 00054 C2E c2e; 00055 C2A c2a; 00056 00057 typedef typename AP::result_type Ares; 00058 00059 public: 00060 00061 typedef AP Approximate_predicate; 00062 typedef EP Exact_predicate; 00063 typedef C2E To_exact_converter; 00064 typedef C2A To_approximate_converter; 00065 00066 typedef typename EP::result_type result_type; 00067 // AP::result_type must be convertible to EP::result_type. 00068 00069 Filtered_predicate() 00070 {} 00071 00072 // These constructors are used for constructive predicates. 00073 // You should try to avoid constructive predicates, as they will construct 00074 // the exact values systematically (in the ctor), rather than lazily. 00075 template <class O> 00076 Filtered_predicate(const O &o1) 00077 : ep(c2e(o1)), ap(c2a(o1)) 00078 {} 00079 00080 template <class O1, class O2> 00081 Filtered_predicate(const O1 &o1, const O2 &o2) 00082 : ep(c2e(o1), c2e(o2)), ap(c2a(o1), c2a(o2)) 00083 {} 00084 00085 #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES 00086 template <typename... Args> 00087 result_type 00088 operator()(const Args&... args) const; 00089 #else 00090 00091 template <class A1> 00092 result_type 00093 operator()(const A1 &a1) const; 00094 00095 template <class A1, class A2> 00096 result_type 00097 operator()(const A1 &a1, const A2 &a2) const; 00098 00099 template <class A1, class A2, class A3> 00100 result_type 00101 operator()(const A1 &a1, const A2 &a2, const A3 &a3) const; 00102 00103 template <class A1, class A2, class A3, class A4> 00104 result_type 00105 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const; 00106 00107 template <class A1, class A2, class A3, class A4, class A5> 00108 result_type 00109 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00110 const A5 &a5) const; 00111 00112 template <class A1, class A2, class A3, class A4, class A5, class A6> 00113 result_type 00114 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00115 const A5 &a5, const A6 &a6) const; 00116 00117 template <class A1, class A2, class A3, class A4, class A5, class A6, 00118 class A7> 00119 result_type 00120 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00121 const A5 &a5, const A6 &a6, const A7 &a7) const; 00122 00123 template <class A1, class A2, class A3, class A4, class A5, class A6, 00124 class A7, class A8> 00125 result_type 00126 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00127 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const; 00128 00129 template <class A1, class A2, class A3, class A4, class A5, class A6, 00130 class A7, class A8, class A9> 00131 result_type 00132 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00133 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, 00134 const A9 &a9) const; 00135 00136 template <class A1, class A2, class A3, class A4, class A5, class A6, 00137 class A7, class A8, class A9, class A10> 00138 result_type 00139 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00140 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, 00141 const A9 &a9, const A10 &a10) const; 00142 00143 // Idem for more than 10 arguments. Do it on demand. 00144 00145 #endif 00146 }; 00147 00148 #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES 00149 00150 template <class EP, class AP, class C2E, class C2A, bool Protection> 00151 template <typename... Args> 00152 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00153 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00154 operator()(const Args&... args) const 00155 { 00156 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00157 // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG 00158 { 00159 Protect_FPU_rounding<Protection> p; 00160 try 00161 { 00162 Ares res = ap(c2a(args)...); 00163 if (is_certain(res)) 00164 return get_certain(res); 00165 } 00166 catch (Uncertain_conversion_exception) {} 00167 } 00168 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00169 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00170 return ep(c2e(args)...); 00171 } 00172 00173 #else 00174 00175 template <class EP, class AP, class C2E, class C2A, bool Protection> 00176 template <class A1> 00177 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00178 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00179 operator()(const A1 &a1) const 00180 { 00181 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00182 { 00183 Protect_FPU_rounding<Protection> p; 00184 try 00185 { 00186 00187 Ares res = ap(c2a(a1)); 00188 if (is_certain(res)) 00189 return get_certain(res); 00190 } 00191 catch (Uncertain_conversion_exception) {} 00192 } 00193 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00194 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00195 return ep(c2e(a1)); 00196 } 00197 00198 template <class EP, class AP, class C2E, class C2A, bool Protection> 00199 template <class A1, class A2> 00200 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00201 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00202 operator()(const A1 &a1, const A2 &a2) const 00203 { 00204 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00205 { 00206 Protect_FPU_rounding<Protection> p; 00207 try 00208 { 00209 Ares res = ap(c2a(a1), c2a(a2)); 00210 if (is_certain(res)) 00211 return get_certain(res); 00212 } 00213 catch (Uncertain_conversion_exception) {} 00214 } 00215 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00216 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00217 return ep(c2e(a1), c2e(a2)); 00218 } 00219 00220 template <class EP, class AP, class C2E, class C2A, bool Protection> 00221 template <class A1, class A2, class A3> 00222 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00223 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00224 operator()(const A1 &a1, const A2 &a2, const A3 &a3) const 00225 { 00226 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00227 { 00228 Protect_FPU_rounding<Protection> p; 00229 try 00230 { 00231 Ares res = ap(c2a(a1), c2a(a2), c2a(a3)); 00232 if (is_certain(res)) 00233 return get_certain(res); 00234 } 00235 catch (Uncertain_conversion_exception) {} 00236 } 00237 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00238 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00239 return ep(c2e(a1), c2e(a2), c2e(a3)); 00240 } 00241 00242 template <class EP, class AP, class C2E, class C2A, bool Protection> 00243 template <class A1, class A2, class A3, class A4> 00244 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00245 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00246 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const 00247 { 00248 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00249 { 00250 Protect_FPU_rounding<Protection> p; 00251 try 00252 { 00253 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4)); 00254 if (is_certain(res)) 00255 return get_certain(res); 00256 } 00257 catch (Uncertain_conversion_exception) {} 00258 } 00259 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00260 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00261 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4)); 00262 } 00263 00264 template <class EP, class AP, class C2E, class C2A, bool Protection> 00265 template <class A1, class A2, class A3, class A4, class A5> 00266 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00267 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00268 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00269 const A5 &a5) const 00270 { 00271 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00272 { 00273 Protect_FPU_rounding<Protection> p; 00274 try 00275 { 00276 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5)); 00277 if (is_certain(res)) 00278 return get_certain(res); 00279 } 00280 catch (Uncertain_conversion_exception) {} 00281 } 00282 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00283 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00284 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5)); 00285 } 00286 00287 template <class EP, class AP, class C2E, class C2A, bool Protection> 00288 template <class A1, class A2, class A3, class A4, class A5, class A6> 00289 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00290 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00291 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00292 const A5 &a5, const A6 &a6) const 00293 { 00294 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00295 { 00296 Protect_FPU_rounding<Protection> p; 00297 try 00298 { 00299 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6)); 00300 if (is_certain(res)) 00301 return get_certain(res); 00302 } 00303 catch (Uncertain_conversion_exception) {} 00304 } 00305 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00306 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00307 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6)); 00308 } 00309 00310 template <class EP, class AP, class C2E, class C2A, bool Protection> 00311 template <class A1, class A2, class A3, class A4, class A5, class A6, 00312 class A7> 00313 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00314 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00315 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00316 const A5 &a5, const A6 &a6, const A7 &a7) const 00317 { 00318 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00319 { 00320 Protect_FPU_rounding<Protection> p; 00321 try 00322 { 00323 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), 00324 c2a(a7)); 00325 if (is_certain(res)) 00326 return get_certain(res); 00327 } 00328 catch (Uncertain_conversion_exception) {} 00329 } 00330 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00331 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00332 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7)); 00333 } 00334 00335 template <class EP, class AP, class C2E, class C2A, bool Protection> 00336 template <class A1, class A2, class A3, class A4, class A5, class A6, 00337 class A7, class A8> 00338 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00339 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00340 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00341 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const 00342 { 00343 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00344 { 00345 Protect_FPU_rounding<Protection> p; 00346 try 00347 { 00348 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), 00349 c2a(a7), c2a(a8)); 00350 if (is_certain(res)) 00351 return get_certain(res); 00352 } 00353 catch (Uncertain_conversion_exception) {} 00354 } 00355 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00356 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00357 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), 00358 c2e(a8)); 00359 } 00360 00361 template <class EP, class AP, class C2E, class C2A, bool Protection> 00362 template <class A1, class A2, class A3, class A4, class A5, class A6, 00363 class A7, class A8, class A9> 00364 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00365 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00366 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00367 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, 00368 const A9 &a9) const 00369 { 00370 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00371 { 00372 Protect_FPU_rounding<Protection> p; 00373 try 00374 { 00375 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), 00376 c2a(a7), c2a(a8), c2a(a9)); 00377 if (is_certain(res)) 00378 return get_certain(res); 00379 } 00380 catch (Uncertain_conversion_exception) {} 00381 } 00382 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00383 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00384 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), 00385 c2e(a8), c2e(a9)); 00386 } 00387 00388 template <class EP, class AP, class C2E, class C2A, bool Protection> 00389 template <class A1, class A2, class A3, class A4, class A5, class A6, 00390 class A7, class A8, class A9, class A10> 00391 typename Filtered_predicate<EP,AP,C2E,C2A,Protection>::result_type 00392 Filtered_predicate<EP,AP,C2E,C2A,Protection>:: 00393 operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, 00394 const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, 00395 const A9 &a9, const A10 &a10) const 00396 { 00397 CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); 00398 { 00399 Protect_FPU_rounding<Protection> p; 00400 try 00401 { 00402 Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6), 00403 c2a(a7), c2a(a8), c2a(a9), c2a(a10)); 00404 if (is_certain(res)) 00405 return get_certain(res); 00406 } 00407 catch (Uncertain_conversion_exception) {} 00408 } 00409 CGAL_BRANCH_PROFILER_BRANCH(tmp); 00410 Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); 00411 return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7), 00412 c2e(a8), c2e(a9), c2e(a10)); 00413 } 00414 00415 #endif 00416 00417 CGAL_END_NAMESPACE 00418 00419 #endif // CGAL_FILTERED_PREDICATE_H