freepooma-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [pooma-dev] Expanding Supported Explicit Instantiations


From: Dave Nystrom
Subject: RE: [pooma-dev] Expanding Supported Explicit Instantiations
Date: Tue, 22 May 2001 13:04:34 -0600 (MDT)

Jeffrey Oldham writes:
 > OK to commit this patch?
 > 
 > Dave Nystrom desired to explicitly instantiate this program:
 > 
 >     #include "Pooma/NewFields.h"
 > 
 >     #define T1 NoGeometry<(int)3>
 >     #define T2 int
 >     #define T3 CompressibleBrick
 >     #define T4 Interval<(int)3>
 >     template View1<Field<T1,T2,T3>,T4>::sv;
 > 
 > I do not know the correct syntax for explicitly instantiating View1's
 > const static bool `sv' if this is even legal.  The attached patch
 > permits instantiating

I first interacted with Arch Robison at KAI about this instantiation problem
and he did not comment that the syntax was wrong.  Also, the KCC prelinker
only instantiates the const static bool 'sv', not anything else.

I'm also curious whether Jim Crotinger's idea of making 'sv' private in the
hope that the compiler could optimize it away was worth considering.

 >     #include "Pooma/NewFields.h"
 > 
 >     #define T1 NoGeometry<(int)3>
 >     #define T2 int
 >     #define T3 CompressibleBrick
 >     #define T4 Interval<(int)3>
 >     template class View1<Field<T1,T2,T3>,T4>;
 > 
 > It also permits
 > 
 >     template View0<Array<2,T2,T3> >;
 > 
 > without first explicitly instantiating Array<2,T2,T3>;
 > 
 > The main idea is to break mutually recursive class definitions by
 > defining alternative `View' classes that contain all the type
 > definitions of their corresponding `View' classes but omit the member
 > functions.  These alternative classes provide the return type for
 > non-templated member functions of Array and Field classes.  These
 > member functions' bodies still use the View classes.  Since the
 > alternative classes' definitions are the same as for the View classes,
 > this trickery works.  If a View class's code changes, the
 > corresponding alternative class's code must also be changed.  This
 > might lead to future maintenance problems.
 > 
 > Stephen Smith provided the insight for the patch so he deserves all
 > positive credit.  Send all criticisms to Jeffrey.
 > 
 > 2001-05-22  Jeffrey D. Oldham <address@hidden>
 >      * Array/Array.h (View0): Modify initial comment to indicate
 >      changes should also be made to AltView0.
 >      (AltView0): New class to avoid explicit instantiation problems.
 >      (ComponentView): Modify initial comment to indicate class should
 >      not be explicitly instantiated.
 >      (Array::read()): Change return type to AltView0.
 >      (Array::operator()()): Likewise.
 > 
 >      * NewField/Field.h (View1): Modify initial comment to indicate
 >      changes should also be made to AltView1.
 >      (AltView1): New class to avoid explicit instantiation problems.
 >      (Field::read()): Change return type to AltView1.
 >      (Field::readAll()): Likewise.
 >      (Field::read(s1)): Likewise.
 >      (Field::operator()()): Likewise.
 >      (Field::all()): Likewise.
 >      (Field::operator()(s1)): Likewise.
 > 
 > Tested on    sequential Linux using gcc 3.0
 > Approved by  ???you???
 > 
 > Thanks,
 > Jeffrey D. Oldham
 > address@hidden: Array/Array.h
 > ===================================================================
 > RCS file: /home/pooma/Repository/r2/src/Array/Array.h,v
 > retrieving revision 1.140
 > diff -c -p -r1.140 Array.h
 > *** Array/Array.h    2001/05/14 21:11:22     1.140
 > --- Array/Array.h    2001/05/22 17:56:30
 > *************** struct View1<Array<Dim, T, EngineTag>, D
 > *** 642,647 ****
 > --- 642,649 ----
 >   // an existing engine cannot be any kind of slice domain.
 >   // Also, bounds checking would make no sense because it would
 >   // reduce to contains(a.domain(), a.domain());
 > + //
 > + // Any changes to this class should also be made to AltView0.
 >   
 >   template<int Dim, class T, class EngineTag>
 >   struct View0<Array<Dim, T, EngineTag> >
 > *************** struct View0<Array<Dim, T, EngineTag> >
 > *** 686,691 ****
 > --- 688,728 ----
 >       }
 >   };
 >   
 > + // AltView0 avoids an instantiation problem that arises when two
 > + // classes use each other.  This class's definition should be exactly
 > + // the same as View0 except omitting member functions.
 > + //
 > + // Do NOT explicitly instantiate this class.
 > + 
 > + template<class ArrayTag>
 > + struct AltView0;
 > + 
 > + template<int Dim, class T, class EngineTag>
 > + struct AltView0<Array<Dim, T, EngineTag> >
 > + {
 > +   // Convenience typedef for the thing we're taking a view of.
 > +   
 > +   typedef Array<Dim, T, EngineTag> Subject_t;
 > + 
 > +   // Deduce domains for the output type.
 > +   // At some point, we need to fix NewDomain1; until then, use
 > +   // the temporary version from Array.h.
 > +   
 > +   typedef typename Subject_t::Engine_t Engine_t;
 > +   typedef typename Subject_t::Domain_t Domain_t;
 > + 
 > +   // Deduce the template parameters for the output type.
 > +   
 > +   typedef typename NewEngine<Engine_t, Domain_t>::Type_t NewEngine_t;
 > +   enum { newDim = NewEngine_t::dimensions };
 > +   typedef typename NewEngine_t::Tag_t NewEngineTag_t;
 > +   
 > +   // The output types.
 > +   
 > +   typedef Array<newDim, T, NewEngineTag_t> Type_t;
 > +   typedef Type_t ReadType_t;
 > + };
 > + 
 >   template<int Dim, class T, class EngineTag>
 >   struct View1<Array<Dim, T, EngineTag>, int>
 >   {
 > *************** struct Patch<Array<Dim, T, EngineTag> >
 > *** 1278,1283 ****
 > --- 1315,1321 ----
 >   
 >   
 > //-----------------------------------------------------------------------------
 >   // ComponentView specialization for Array.
 > + // Changes to ComponentView should also be made to AltComponentView.
 >   
 > //-----------------------------------------------------------------------------
 >   
 >   template<int Dim, class T, class EngineTag>
 > *************** struct ComponentView<Components, Array<D
 > *** 1314,1321 ****
 >   };
 >   
 >   
 > //-----------------------------------------------------------------------------
 > ! // AltComponentView gets around the problem that instantiation problem that
 > ! // arises when two classes use each other.
 >   
 > //-----------------------------------------------------------------------------
 >   
 >   template<class Components, class Arr>
 > --- 1352,1362 ----
 >   };
 >   
 >   
 > //-----------------------------------------------------------------------------
 > ! // AltComponentView avoids an instantiation problem that arises when
 > ! // two classes use each other.  These classes' definitions should be
 > ! // exactly the same as ComponentView except omitting member functions.
 > ! //
 > ! // Do NOT explicitly instantiate these alternative classes.
 >   
 > //-----------------------------------------------------------------------------
 >   
 >   template<class Components, class Arr>
 > *************** public:
 > *** 1785,1791 ****
 >     // A zero-argument version of operator(), which takes a view of 
 >     // array's domain, is also supplied.
 >   
 > !   typename View0<This_t>::ReadType_t 
 >     read() const
 >       {
 >         typedef View0<This_t> Ret_t;
 > --- 1826,1832 ----
 >     // A zero-argument version of operator(), which takes a view of 
 >     // array's domain, is also supplied.
 >   
 > !   typename AltView0<This_t>::ReadType_t 
 >     read() const
 >       {
 >         typedef View0<This_t> Ret_t;
 > *************** public:
 > *** 1855,1861 ****
 >         return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6, s7);
 >       }
 >   
 > !   typename View0<This_t>::Type_t 
 >     operator()() const
 >       {
 >         typedef View0<This_t> Ret_t;
 > --- 1896,1902 ----
 >         return Ret_t::makeRead(*this, s1, s2, s3, s4, s5, s6, s7);
 >       }
 >   
 > !   typename AltView0<This_t>::Type_t 
 >     operator()() const
 >       {
 >         typedef View0<This_t> Ret_t;
 > Index: NewField/Field.h
 > ===================================================================
 > RCS file: /home/pooma/Repository/r2/src/NewField/Field.h,v
 > retrieving revision 1.13
 > diff -c -p -r1.13 Field.h
 > *** NewField/Field.h 2001/05/14 21:11:24     1.13
 > --- NewField/Field.h 2001/05/22 17:56:34
 > *************** struct View1Implementation<Field<Geometr
 > *** 424,429 ****
 > --- 424,431 ----
 >   
 >   
 > //-----------------------------------------------------------------------------
 >   // View1<Field, S1> specialization for indexing a field with a single 
 > domain.
 > + //
 > + // Any changes to View1 should also be made to AltView1.
 >   
 > //-----------------------------------------------------------------------------
 >   
 >   template<class GeometryTag, class T, class EngineTag, class Sub1>
 > *************** struct View1<Field<GeometryTag, T, Engin
 > *** 473,478 ****
 > --- 475,482 ----
 >   
 >   
 > //-----------------------------------------------------------------------------
 >   // View1<Field, int> specialization for indexing a field with an int.
 > + //
 > + // Any changes to View1 should also be made to AltView1.
 >   
 > //-----------------------------------------------------------------------------
 >   
 >   template<class GeometryTag, class T, class EngineTag>
 > *************** struct View1<Field<GeometryTag, T, Engin
 > *** 516,521 ****
 > --- 520,590 ----
 >   
 >   
 >   
 > //-----------------------------------------------------------------------------
 > + // AltView1 avoids an instantiation problem that arises when two
 > + // classes use each other.  This class's definition should be exactly
 > + // the same as View1 except omitting member functions.
 > + //
 > + // Do NOT explicitly instantiate this class.
 > + 
 > //-----------------------------------------------------------------------------
 > + 
 > + template<class FieldTag, class DomainTag>
 > + struct AltView1;
 > + 
 > + template<class GeometryTag, class T, class EngineTag, class Sub1>
 > + struct AltView1<Field<GeometryTag, T, EngineTag>, Sub1>
 > + {
 > +   // Convenience typedef for the thing we're taking a view of.
 > +   
 > +   typedef Field<GeometryTag, T, EngineTag> Subject_t;
 > + 
 > +   // Deduce domains for the output type.
 > +   // At some point, we need to fix NewDomain1; until then, use
 > +   // the temporary version from NewDomain.h.
 > +   
 > +   typedef typename Subject_t::Domain_t Domain_t;
 > +   typedef TemporaryNewDomain1<Domain_t, Sub1> NewDomain_t;
 > +   typedef typename NewDomain_t::SliceType_t SDomain_t;
 > +   
 > +   // Deduce appropriate version of implementation to dispatch to.
 > +   
 > +   static const bool sv = DomainTraits<SDomain_t>::singleValued;
 > +   typedef View1Implementation<Subject_t, SDomain_t, sv> Dispatch_t;
 > + 
 > +   // The optimized domain combiner.
 > +   
 > +   typedef CombineDomainOpt<NewDomain_t, sv> Combine_t;
 > +   
 > +   // The return types.
 > +   
 > +   typedef typename Dispatch_t::ReadType_t ReadType_t;
 > +   typedef typename Dispatch_t::Type_t Type_t;
 > + };
 > + 
 > + 
 > + 
 > //-----------------------------------------------------------------------------
 > + // AltView1 avoids an instantiation problem that arises when two
 > + // classes use each other.  This class's definition should be exactly
 > + // the same as View1 except omitting member functions.
 > + //
 > + // Do NOT explicitly instantiate this class.
 > + 
 > //-----------------------------------------------------------------------------
 > + 
 > + template<class GeometryTag, class T, class EngineTag>
 > + struct AltView1<Field<GeometryTag, T, EngineTag>, int>
 > + {
 > +   // Convenience typedef for the thing we're taking a view of.
 > +   
 > +   typedef Field<GeometryTag, T, EngineTag> Subject_t;
 > + 
 > +   // The return types.
 > +   
 > +   typedef typename Subject_t::Element_t ReadType_t;
 > +   typedef typename Subject_t::ElementRef_t Type_t;
 > + 
 > + };
 > + 
 > + 
 > + 
 > //-----------------------------------------------------------------------------
 >   // View2<Field, S1, S2> specialization for indexing a field with two
 >   // domains.
 >   
 > //-----------------------------------------------------------------------------
 > *************** public:
 > *** 1010,1023 ****
 >     // version returns a view of the physical domain and the 'All'-suffixed
 >     // versions return a view of the total domain.
 >   
 > !   inline typename View1<This_t, Domain_t>::ReadType_t 
 >     read() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 >         return Ret_t::makeRead(*this, physicalDomain());
 >       }
 >   
 > !   inline typename View1<This_t, Domain_t>::ReadType_t 
 >     readAll() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 > --- 1079,1092 ----
 >     // version returns a view of the physical domain and the 'All'-suffixed
 >     // versions return a view of the total domain.
 >   
 > !   inline typename AltView1<This_t, Domain_t>::ReadType_t 
 >     read() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 >         return Ret_t::makeRead(*this, physicalDomain());
 >       }
 >   
 > !   inline typename AltView1<This_t, Domain_t>::ReadType_t 
 >     readAll() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 > *************** public:
 > *** 1025,1031 ****
 >       }
 >   
 >     template<class Sub1> 
 > !   inline typename View1<This_t, Sub1>::ReadType_t 
 >     read(const Sub1 &s1) const
 >       {
 >         typedef View1<This_t, Sub1> Ret_t;
 > --- 1094,1100 ----
 >       }
 >   
 >     template<class Sub1> 
 > !   inline typename AltView1<This_t, Sub1>::ReadType_t 
 >     read(const Sub1 &s1) const
 >       {
 >         typedef View1<This_t, Sub1> Ret_t;
 > *************** public:
 > *** 1048,1061 ****
 >         return Ret_t::makeRead(*this, s1, s2, s3);
 >       }
 >   
 > !   inline typename View1<This_t, Domain_t>::Type_t 
 >     operator()() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 >         return Ret_t::make(*this, physicalDomain());
 >       }
 >   
 > !   inline typename View1<This_t, Domain_t>::Type_t 
 >     all() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 > --- 1117,1130 ----
 >         return Ret_t::makeRead(*this, s1, s2, s3);
 >       }
 >   
 > !   inline typename AltView1<This_t, Domain_t>::Type_t 
 >     operator()() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 >         return Ret_t::make(*this, physicalDomain());
 >       }
 >   
 > !   inline typename AltView1<This_t, Domain_t>::Type_t 
 >     all() const
 >       {
 >         typedef View1<This_t, Domain_t> Ret_t;
 > *************** public:
 > *** 1063,1069 ****
 >       }
 >   
 >     template<class Sub1> 
 > !   inline typename View1<This_t, Sub1>::Type_t 
 >     operator()(const Sub1 &s1) const
 >       {
 >         typedef View1<This_t, Sub1> Ret_t;
 > --- 1132,1138 ----
 >       }
 >   
 >     template<class Sub1> 
 > !   inline typename AltView1<This_t, Sub1>::Type_t 
 >     operator()(const Sub1 &s1) const
 >       {
 >         typedef View1<This_t, Sub1> Ret_t;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]