473,698 Members | 2,603 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

a template meta problem

Hi,

I have a problem with extending some existing code. In a simplified
form, the problem looks like this:

I have four types, A, B, C, and D. Each A refers to zero, one, or more
B's and each B can be child to zero, one, or more A's. I just call that
"A is a parent of B", and "B is a child of A". The same goes for B and
C and for C and D. So A is only a parent, B and C are both parents and
children, and D is only a child.
I have many algorithms dealing with these. Most them are templates and
work on either all types, or all parent types, or all child types (and
some even only work on grandparent types). For this to work, the types
look somewhat like this:

// Beware, uncompiled code ahead!

struct tmp_nil {};

template<bool b> struct tmp_bool { enum {result=b}; };

class A;
class B;
class C;
class D;

class A {
public:
typedef tmp_bool<false> is_child;
typedef tmp_bool<true > is_parent;
typedef B child_t;
};

class B {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<true > is_parent;
typedef A parent_t;
typedef C child_t;
};

class C {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<true > is_parent;
typedef B parent_t;
typedef D child_t;
};

class D {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<false> is_parent;
typedef C parent_t;
};

For example, if some algorithm needs to work on a type and recursivly
on all children and grandchildren, what the code does is this:

class some_class {
public:
//...

// this is called by users and does the recursive downstepping
template<class T> void some_algorithm( const T& obj)
{
// do some real work with 'obj'
detail::some_al gorithm_(obj,ty pename T::is_parent()) ; // recurse
}

//...

private:
//...

// some_algorithm( )'s implementation for parents
template<class T> void some_algorithm_ (const T& obj, tmp_bool<true > /*is_parent*/)
{
for( <all children refered to by 'obj'> ) {
typename T::child_t& child = /*...*/;
some_algorithm( child);
}
}

// some_algorithm( )'s implementation for childless types
template<class T> void some_algorithm_ (const T& obj, tmp_bool<false> /*is_parent*/)
{
// no children, so nothing to do here
}

//...

};

This worked all very well for years. However, now my task is to introduce
some type B2, that's also a child to A (but not a parent to C):

class B2 {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<false> is_parent;
typedef A parent_t;
};

Now, I suppose parents would need to change like this:

template<typena me Head, class Tail> struct tmp_list {};

class A {
public:
typedef tmp_bool<false> is_child;
typedef tmp_bool<true > is_parent;
typedef tmp_list< B, tmp_list<C,tmp_ nil> >
child_list;
};

I know how to deal with such recursive type lists. However, I only know
how to do this with _class_ templates. But it's _functon_ templates that
I have as algorithms, and they are stuck in some class (the 'some_class'
in the example above above) that provides all the necessary functionality
(retrieve objects etc.) for them. (And they also need to be members of it
because 'some_class', in reality being a friend to A, B, C, and D, is the
only thing that can actually get at the relevant information -- which is
not needed by users of A, B, C, and D.)
So given
template<class T> void some_class::som e_algorithm_(co nst T&,tmp_bool<tru e>)
how can I make it call
template<class T> void some_class::som e_algorithm(con st T&)
for _all_ children in the child list of (the new version of) A?

As for the constraints I'm working under: The code is "mine". I am free
to change it as I need as long as the public interface doesn't change
more than ansolutely necessary. It is, however, quite a lot of code,
with many algorithms that have been maintained and fixed for years. And,
as always, the deadline is a rather tight one.
That's why I want to "implant" B2 with as little changes as necessary.
Right now it seems it's just a syntactic problem.

TIA,

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."
Eric Jarvis
Dec 1 '05 #1
6 1576
Hendrik Schober wrote:
Hi,

I have a problem with extending some existing code. In a simplified
form, the problem looks like this: .... Right now it seems it's just a syntactic problem.


Any chance of creating a brief and compilable piece. I don't get
exactly how B2 plays into this.
Dec 1 '05 #2
Hendrik Schober wrote:
Hi,

I have a problem with extending some existing code. In a simplified
form, the problem looks like this:

I have four types, A, B, C, and D. Each A refers to zero, one, or more
B's and each B can be child to zero, one, or more A's. I just call that
"A is a parent of B", and "B is a child of A". The same goes for B and
C and for C and D. So A is only a parent, B and C are both parents and
children, and D is only a child.
I have many algorithms dealing with these. Most them are templates and
work on either all types, or all parent types, or all child types (and
some even only work on grandparent types). For this to work, the types
look somewhat like this:

// Beware, uncompiled code ahead!

struct tmp_nil {};

template<bool b> struct tmp_bool { enum {result=b}; };

class A;
class B;
class C;
class D;

class A {
public:
typedef tmp_bool<false> is_child;
typedef tmp_bool<true > is_parent;
typedef B child_t;
};

class B {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<true > is_parent;
typedef A parent_t;
typedef C child_t;
};

class C {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<true > is_parent;
typedef B parent_t;
typedef D child_t;
};

class D {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<false> is_parent;
typedef C parent_t;
};

For example, if some algorithm needs to work on a type and recursivly
on all children and grandchildren, what the code does is this:

class some_class {
public:
//...

// this is called by users and does the recursive downstepping
template<class T> void some_algorithm( const T& obj)
{
// do some real work with 'obj'
detail::some_al gorithm_(obj,ty pename T::is_parent()) ; // recurse
No namespace/class called detail is given. I'm assuming that you meant
to call the private template member functions given below and not a
function that is not shown.
}

//...

private:
//...

// some_algorithm( )'s implementation for parents
template<class T> void some_algorithm_ (const T& obj, tmp_bool<true > /*is_parent*/)
{
for( <all children refered to by 'obj'> ) {
typename T::child_t& child = /*...*/;
some_algorithm( child);
}
}

// some_algorithm( )'s implementation for childless types
template<class T> void some_algorithm_ (const T& obj, tmp_bool<false> /*is_parent*/)
{
// no children, so nothing to do here
}

//...

};

This worked all very well for years. However, now my task is to introduce
some type B2, that's also a child to A (but not a parent to C):

class B2 {
public:
typedef tmp_bool<true > is_child;
typedef tmp_bool<false> is_parent;
typedef A parent_t;
};

Now, I suppose parents would need to change like this:

template<typena me Head, class Tail> struct tmp_list {};

class A {
public:
typedef tmp_bool<false> is_child;
typedef tmp_bool<true > is_parent;
typedef tmp_list< B, tmp_list<C,tmp_ nil> >
child_list;
I think you meant B2 not C in this typedef.
};

I know how to deal with such recursive type lists. However, I only know
how to do this with _class_ templates. But it's _functon_ templates that
I have as algorithms, and they are stuck in some class (the 'some_class'
in the example above above) that provides all the necessary functionality
(retrieve objects etc.) for them. (And they also need to be members of it
because 'some_class', in reality being a friend to A, B, C, and D, is the
only thing that can actually get at the relevant information -- which is
not needed by users of A, B, C, and D.)
So given
template<class T> void some_class::som e_algorithm_(co nst T&,tmp_bool<tru e>)
how can I make it call
template<class T> void some_class::som e_algorithm(con st T&)
for _all_ children in the child list of (the new version of) A?

[snip]

Before we can answer that, I think we need to see how you plan to
reference children of A. You have given us the typedef for the child
list, but how do you declare a child (or a pointer or reference to a
child) which is a member of A and a type in that list?

Cheers! --M

Dec 1 '05 #3
Gianni Mariani <gi*******@mari ani.ws> wrote:
Hendrik Schober wrote:
Hi,

I have a problem with extending some existing code. In a simplified
form, the problem looks like this: ...
Right now it seems it's just a syntactic problem.


Any chance of creating a brief and compilable piece.


My problem is that I have no idea what a compilable
piece would look like.
I don't get
exactly how B2 plays into this.

It's a sibling to B, except that it isn't a parent to C.

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."
Eric Jarvis
Dec 1 '05 #4
mlimber <ml*****@gmail. com> wrote:
[...]
For example, if some algorithm needs to work on a type and recursivly
on all children and grandchildren, what the code does is this:

class some_class {
public:
//...

// this is called by users and does the recursive downstepping
template<class T> void some_algorithm( const T& obj)
{
// do some real work with 'obj'
detail::some_al gorithm_(obj,ty pename T::is_parent()) ; // recurse
No namespace/class called detail is given. I'm assuming that you meant
to call the private template member functions given below and not a
function that is not shown.


Yep. Sorry for that. I first made this example using
free functions. Only later I realized that the fact
that they are members might be of some (syntactic)
significance. So I changed the example and forgot
this.
[...]
Now, I suppose parents would need to change like this:

template<typena me Head, class Tail> struct tmp_list {};

class A {
public:
typedef tmp_bool<false> is_child;
typedef tmp_bool<true > is_parent;
typedef tmp_list< B, tmp_list<C,tmp_ nil> >
child_list;
I think you meant B2 not C in this typedef.


Um, yeah. Sorry. :(
[...]

Before we can answer that, I think we need to see how you plan to
reference children of A. You have given us the typedef for the child
list, but how do you declare a child (or a pointer or reference to a
child) which is a member of A and a type in that list?
I don't see how this is relevant.
Maybe my OP was a bit misleading in its terminology.
<sigh>

I'll try to clarify:
Instances of A can be parents to instances of B. This
is a /run-time/ relationship. It could be achieved by
simple pointers. (In the real code, it is achieved by
each A having a list of IDs that (exclusivly) refer to
Bs. 'some_class' has some functions that hand out
references to the real objects when given the right
IDs.)
However, the important part is: Which A refers to
which B is a /run-time/ thing. That instances of A
always refer to instances of B is a /compile-time/
thing.

I haven't shown the actual run-time referencing stuff,
because I think it isn't relevant. Just assume that A
has some member templates that, given B as a template
arg, let you iterate over a list of instances of B.
The compile-time stuff needs to find out that instances
of A always refer to instances of B as children (and
that thus B should be passed to those member templates
of A).
This works for several years.
I now need to extend that compile-time mechanism so that
it finds out that instances of A refer to instances of B
/and/ instances of B2 as children and then iterates over
both child lists.
(And I need to have the very same algorithms working
with B-C and C-D relationships as well, where there's
only one child.)

What I am having problems with is that I need to change
the mechanics which, at compile time, used to find out
/if/ there's a (one) child type and, if so, iterated,
at run-time, over /the/ (one) child list into some
mechanics that, at compile-time, find out /how many/
child types there are and generates the code to, at
run-time, iterate over /all/ of those child lists.

I hope that's clearer now.
Cheers! --M

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."
Eric Jarvis
Dec 1 '05 #5
Hendrik Schober wrote:
[snip]
I now need to extend that compile-time mechanism so that
it finds out that instances of A refer to instances of B
/and/ instances of B2 as children and then iterates over
both child lists.
(And I need to have the very same algorithms working
with B-C and C-D relationships as well, where there's
only one child.)

What I am having problems with is that I need to change
the mechanics which, at compile time, used to find out
/if/ there's a (one) child type and, if so, iterated,
at run-time, over /the/ (one) child list into some
mechanics that, at compile-time, find out /how many/
child types there are and generates the code to, at
run-time, iterate over /all/ of those child lists.

I hope that's clearer now.


Ok. You said previously that you know how to recurse the typelists
already. Could you change each parent object (A, B, and C) to have a
typelist of children rather than a simple child type, and then change
your functions to iterate over those lists? That way there is no
operational difference between having one child type and multiple, but
only A would actually have multiple types (viz. B and B2) in its list.
The remaining challenge would be to acquire the proper child object,
but that could be accomplished by adding to each parent class a
template member function that is specialized for each of its children,
e.g.,

class A
{
// ...
template <class Child> Child GetChild();
template <> B& GetChild<B >() { /* return a B */ }
template <> B2& GetChild<B2>() { /* return a B2 */ }
};

Then your algorithm would use obj.Get<ChildTy pe>() to retrieve the
child for processing. ChildType would be determined by the current
"iteration" of the child typelist.

Cheers! --M

Dec 1 '05 #6
mlimber <ml*****@gmail. com> wrote:
[...]
Ok. You said previously that you know how to recurse the typelists
already. Could you change each parent object (A, B, and C) to have a
typelist of children rather than a simple child type, and then change
your functions to iterate over those lists? That way there is no
operational difference between having one child type and multiple, but
only A would actually have multiple types (viz. B and B2) in its list.
That's what I was planning. However, I didn't see a
way to iterate over typelists except by using class
templates. But I just realized I could have a function
recursivly calling itself with the tail of the list.
If the function has an overload of the tmp_nil type,
this would stop the recursion.
The remaining challenge would be to acquire the proper child object,
That's no problem. I had solved that before. :)
I just didn't know how to process TMP lists using
function templates...

Thanks for your help! I like to have things set up in
my head a few days before I start implementing them.
[...]
Cheers! --M


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."
Eric Jarvis
Dec 2 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2217
by: Ingo Nolden | last post by:
Hi, I want to write a template class that holds another class that uses the same template. This recursion should stop after a predefined number. I think it's either impossible or easy, but I have no idea right now :-( A simplified version is here: template< unsigned Depth > class Foo
8
1371
by: Tjerk Wolterink | last post by:
I have xml inpput like this: <meta:empty/> And xsl like this: <xsl:template match="meta:empty">A</xsl:template> <xsl:template match="//meta:*">B</xsl:template>
8
3022
by: fernandezr | last post by:
I would like to use a user control as a template inside a repeater. Some of the fields in the control should be hidden depending on whether or not there is data. I'm still a ASP .Net newbie so the way I'm going about doing this might be a little off. I'd appreciate some help. Below is the code I have thus far but I'm not sure how to reference the user control within the foreach loop. <asp:Panel ID="pnlRosterProfile" runat="Server" />
8
2281
by: Jon Rea | last post by:
http://osl.iu.edu/~tveldhui/papers/Template-Metaprograms/meta-art.html Can anyone shed some light on the need for stuff like this when using any of the most modern compilers? If i have a function : double Square( double d ) { return d * d;
6
2341
by: bogus1one | last post by:
Hi All Given the following: // NamespaceTemplate.cpp : Defines the entry point for the console application. // #include "stdafx.h"
7
7961
by: Kevin | last post by:
I'm creating a template to support state machines. In doing so, I need to pass an enumeration for the number of transitions and a non type parameter for the range of the enum (to allow me to allocate an array of pointers big enough to hold one entry for each transition). My template declaration looks roughly like this: template <class TRANSITION, int NUMTRANSITIONS> class StateMachine { ***SNIP*** void RegisterTransition(TRANSITION...
3
1849
by: stdlib99 | last post by:
Hi, I have a simple question regarding templates and meta programming. I am going to try and work my way through the C++ Template Metaprogramming, a book by David Abrahams and Aleksey Gurtovoy. I’m not doing this because I want to be a Meta Programming guru (because a lot of that stuff looks too crazy for use in the real world). Rather I want to learn heavyweight templates and this is the only
4
2500
by: z55177 | last post by:
My domain: http://www.esthevision.cz/ This is the cause of my problem. The template is supposed to look somewhat like this: PINK STRIPE http://themebot.com/website-templates/ht... I created an extra copy of it called Natvrdo, since I modified the logo. Okay, I have this in my HTML (Natvrdo being the CSS style sheet) This is what I have in my index.html:
2
6637
by: Clyde | last post by:
Hi, what i'm trying to do is: /////////////// Code Start template <class TType, int* p = 0> class Template { public:
0
8680
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8899
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7738
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6528
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5861
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4371
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2335
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.