[Dune] specializing template classes for Dune::Grid
Jö Fahlke
jorrit at jorrit.de
Mon Sep 1 23:01:03 CEST 2014
Basically, what you want is SFINAE and
Dune::Capabilities::hasSingleGeometryType<Grid>. SFINAE means "substitution
failure is not an error". It works like this: instead of
template<class G>
struct SomeClass;
template<>
struct SomeClass<OneDGrid>
{ /*...*/ };
you do something like this:
template<class G, class Dummy = void>
struct SomeClass;
template<class G>
struct SomeClass<G, typename std::enable_if<G::dimension == 1>::type>
{ /* specialization for dim==1 */ };
The way this works is that when you instantiate SomeClass<SomeGrid>, the
compiler enumerates all the specializations of the template SomeClass. The
extra parameter Dummy is not given and so defaults to void. It then tries
whether it can instantiate each specialization with the parameters G=SomeGrid
and Dummy=void. If SomeGrid::dimension == 1, then in the specialization above
the second parameter will become enable_if<true>::type, which is void, so the
specialization is viable and takes precedence over the general template.
If SomeGrid::dimension != 1 however, then in the specialization above the
second parameter will become enable_if<false>::type. But enable_if<false> has
no member type, so the attempt to instantiate the template results in a
substitution failure. But, since "substitution failure is not an error", this
just means that the specialization is simply removed from the list of
candidates for this instantiation, and what remains is the general template.
The other specialization can be done like this:
template<class G>
struct SomeClass<G, typename std::enable_if<
G::dimension == 2 &&
Dune::Capabilities::hasSingleGeometryType<G>::topologyId == topologyIdForQuad
>::type>
{ /* specialization for dim==1 */ };
Here, a substitution failure can actually occur also if
hasSingleGeometryType<SomeGrid> has no member topologyId. But that just means
that SomeGrid can contain triangles in addition to quads, so you probably
don't want to handle that anyway.
I saw enable_if first in boost, and it has some fairly extensive
documentation[1]. It has made it into the standard by now. Dune also
contained an implementation of enable_if at some point.
[1] http://www.boost.org/doc/libs/1_56_0/libs/core/doc/html/core/enable_if.html
Hope this helps,
Jö.
Am Mon, 1. Sep 2014, 22:07:15 +0200 schrieb Matteo Semplice:
> Date: Mon, 01 Sep 2014 22:07:15 +0200
> From: Matteo Semplice <matteo.semplice at unito.it>
> To: dune <dune at dune-project.org>
> Subject: [Dune] specializing template classes for Dune::Grid
> X-No-Auth: unauthenticated sender
> X-IControl-Milter-MD5SUM: b896b3bd8c6043342bbe89d4fe6f0d28
> X-No-Relay: not in my network
> X-Icontrol: Sent by Inrete Icontrol
> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101
> Icedove/24.7.0
> X-IControl-Milter-Checked: yes (IControlServer: opterone SrcIpType:
> UnTrusted SrcIpHeaderType: Undefined Authenticated: yes)
> X-IControl-Milter-SPF-Checked: yes (IControlServer: opterone HeloSPFType:
> unknown FromSPFType: none HeloHeaderSPFType: Undefined FromHeaderSPFType:
> none)
> X-IControl-Milter-MD5SUM: b896b3bd8c6043342bbe89d4fe6f0d28
> X-Inrete-Amavisjob-Virus-Scanned: PDAmail Multiple Antivirus with ClamAv
> X-Inrete-Amavisjob-Service-Runned: 6 (s81K7Fq5030666)
> X-Inrete-Amavisjob-Service-Disabled: No Service disabled (s81K7Fq5030666)
> X-Spam-Flag: No
> X-Envelope-From: <matteo.semplice at unito.it>
>
> Dear duners,
> my last attempt to update to version 2.3 halted on specializing
> a class that depend on a grid type as template parameter and, after
> the new alugrid module and the updated UG licence, I would like to
> give it another go...
>
> I have a class R that depends on the template parameter G, which is
> a Dune Grid. Most of the methods of the class depend on the Grid
> dimension and on the Grid's cell type, so in order to implement
> them, I need to specialize the class for
> 1) any grid in 1 spatial dimenion
> 2) any grid in 2 spatial dimensions based on quad
>
> My old implementation based on dune 2.2 had actually 3
> specializations for Dune::OneDGrid, for Dune::AlbertaGrid<1,1>, and
> for Dune::ALUCubeGrid<2,2>, the first two being identical and I used
> some #define's in order not to rewrite the 1d code twice. However, I
> couldn't get the correct replacement for Dune::ALUCubeGrid<2,2> in
> the new naming scheme of dune 2.3 that would make the 2d code to
> compile.
>
> So, the question is if it is possible to specialize as in (1) and
> (2), so that one implementation will take care of both
> Dune::OneDGrid and Dune::AlbertaGrid<1,1> and the other
> implementation of AluGrid and UG based on quad. This, of course,
> would be the most elegant solution.
>
> If not, what is the translation of Dune::ALUCubeGrid<2,2> in the new
> naming scheme of dune 2.3?
>
> Thanks in advance!
>
> Best,
> Matteo
>
> _______________________________________________
> Dune mailing list
> Dune at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune
>
--
Jorrit (Jö) Fahlke, Institute for Computational und Applied Mathematics,
University of Münster, Orleans-Ring 10, D-48149 Münster
Tel: +49 251 83 35146 Fax: +49 251 83 32729
In the beginning the Universe was created. This has made a lot of
people very angry and been widely regarded as a bad move.
-- Douglas Adams
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 828 bytes
Desc: Digital signature
URL: <https://lists.dune-project.org/pipermail/dune/attachments/20140901/b7473f5b/attachment.sig>
More information about the Dune
mailing list