BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Filtered_predicate.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines