mirror of https://github.com/CGAL/cgal
Inheriting from the Filtered kernel to reduce code duplication
This commit is contained in:
parent
0470748e12
commit
59811d576a
|
|
@ -25,6 +25,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/basic.h>
|
||||||
#include <CGAL/config.h>
|
#include <CGAL/config.h>
|
||||||
|
#include <CGAL/Filtered_predicate.h>
|
||||||
#include <CGAL/Interval_nt.h>
|
#include <CGAL/Interval_nt.h>
|
||||||
#include <CGAL/Uncertain.h>
|
#include <CGAL/Uncertain.h>
|
||||||
#include <CGAL/Profile_counter.h>
|
#include <CGAL/Profile_counter.h>
|
||||||
|
|
@ -50,380 +51,21 @@ namespace CGAL {
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection = true>
|
template <class EP, class AP, class C2E, class C2A, bool Protection = true>
|
||||||
class Filtered_periodic_predicate_2
|
class Filtered_periodic_predicate_2
|
||||||
|
: public Filtered_predicate <EP, AP, C2E, C2A, Protection>
|
||||||
{
|
{
|
||||||
EP ep;
|
typedef Filtered_predicate<EP, AP, C2E, C2A, Protection> Base;
|
||||||
AP ap;
|
|
||||||
C2E c2e;
|
|
||||||
C2A c2a;
|
|
||||||
|
|
||||||
typedef typename AP::result_type Ares;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typename AP::Iso_rectangle_2 * _domain;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Filtered_periodic_predicate_2() : Base() {}
|
||||||
typedef AP Approximate_predicate;
|
|
||||||
typedef EP Exact_predicate;
|
|
||||||
typedef C2E To_exact_converter;
|
|
||||||
typedef C2A To_approximate_converter;
|
|
||||||
|
|
||||||
typedef typename EP::result_type result_type;
|
|
||||||
// AP::result_type must be convertible to EP::result_type.
|
|
||||||
|
|
||||||
Filtered_periodic_predicate_2()
|
|
||||||
{}
|
|
||||||
|
|
||||||
// These constructors are used for constructive predicates.
|
// These constructors are used for constructive predicates.
|
||||||
// You should try to avoid constructive predicates, as they will construct
|
// You should try to avoid constructive predicates, as they will construct
|
||||||
// the exact values systematically (in the ctor), rather than lazily.
|
// the exact values systematically (in the ctor), rather than lazily.
|
||||||
template <class OE, class OA>
|
template <class OE, class OA>
|
||||||
Filtered_periodic_predicate_2(const OE * oe, const OA * oa)
|
Filtered_periodic_predicate_2(const OE * oe, const OA * oa) : Base(EP(oe), AP(oa)) {}
|
||||||
: ep(oe), ap(oa)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// template <class O>
|
|
||||||
//Filtered_periodic_predicate(const O * o)
|
|
||||||
// : ep(&c2e(*o)), ap(&c2a(*o)) {}
|
|
||||||
|
|
||||||
// template <class O1, class O2>
|
|
||||||
//Filtered_periodic_predicate(const O1 &o1, const O2 &o2)
|
|
||||||
// : ep(c2e(o1), c2e(o2)), ap(c2a(o1), c2a(o2))
|
|
||||||
//{}
|
|
||||||
|
|
||||||
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
||||||
template <typename... Args>
|
|
||||||
result_type
|
|
||||||
operator()(const Args&... args) const;
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <class A1>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1) const;
|
|
||||||
|
|
||||||
template <class A1, class A2>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8, class A9>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8,
|
|
||||||
const A9 &a9) const;
|
|
||||||
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8, class A9, class A10>
|
|
||||||
result_type
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8,
|
|
||||||
const A9 &a9, const A10 &a10) const;
|
|
||||||
|
|
||||||
// Idem for more than 10 arguments. Do it on demand.
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <typename... Args>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const Args&... args) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
// Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(args)...);
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
Ares res = ap(c2a(a1));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6),
|
|
||||||
c2a(a7));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6),
|
|
||||||
c2a(a7), c2a(a8));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7),
|
|
||||||
c2e(a8));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8, class A9>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8,
|
|
||||||
const A9 &a9) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6),
|
|
||||||
c2a(a7), c2a(a8), c2a(a9));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7),
|
|
||||||
c2e(a8), c2e(a9));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EP, class AP, class C2E, class C2A, bool Protection>
|
|
||||||
template <class A1, class A2, class A3, class A4, class A5, class A6,
|
|
||||||
class A7, class A8, class A9, class A10>
|
|
||||||
typename Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::result_type
|
|
||||||
Filtered_periodic_predicate_2<EP,AP,C2E,C2A,Protection>::
|
|
||||||
operator()(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4,
|
|
||||||
const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8,
|
|
||||||
const A9 &a9, const A10 &a10) const
|
|
||||||
{
|
|
||||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
|
||||||
{
|
|
||||||
Protect_FPU_rounding<Protection> p;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Ares res = ap(c2a(a1), c2a(a2), c2a(a3), c2a(a4), c2a(a5), c2a(a6),
|
|
||||||
c2a(a7), c2a(a8), c2a(a9), c2a(a10));
|
|
||||||
if (is_certain(res))
|
|
||||||
return get_certain(res);
|
|
||||||
}
|
|
||||||
catch (Uncertain_conversion_exception) {}
|
|
||||||
}
|
|
||||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
|
||||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
|
||||||
return ep(c2e(a1), c2e(a2), c2e(a3), c2e(a4), c2e(a5), c2e(a6), c2e(a7),
|
|
||||||
c2e(a8), c2e(a9), c2e(a10));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The Offset_converter is parametrized by a usual kernel converter,
|
// The Offset_converter is parametrized by a usual kernel converter,
|
||||||
// and adds the conversions for Offsets.
|
// and adds the conversions for Offsets.
|
||||||
template < typename Converter >
|
template < typename Converter >
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue