473,614 Members | 2,084 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Compile-time introspection

Is there a way to generate a series of statements based on the data members of
a structure at compile time?

I have a function that reverses the endianness of any data structure:

/// Reverse the endianness of a data structure "in place".
template <typename T>
void reverseEndian(T &);

Using boost, it is possible to provide the default implementation for all POD
types (i.e. simply reverse the bytes in the data item's representation) .

Until today, I have purposely not provided the implementation for structures,
forcing the user of the function to provide an implementation for each
structure, for example:

struct S
{
int a;
float b;
double c;
};

template <void reverseEndian(S & s)
{
// Function body -- can this be automated?
reverseEndian<> (s.a);
reverseEndian<> (s.b);
reverseEndian<> (s.c);
}

Is it possible to automatically generate the contents of the specialization?
This calls for introspection (the language feature, not the Zen philosophy),
and so far I have not found any way to do it, portable or otherwise.

-dr
Feb 18 '07 #1
14 4196
Dave Rahardja wrote:
Is there a way to generate a series of statements based on the data members of
a structure at compile time?

I have a function that reverses the endianness of any data structure:

/// Reverse the endianness of a data structure "in place".
template <typename T>
void reverseEndian(T &);

Using boost, it is possible to provide the default implementation for all POD
types (i.e. simply reverse the bytes in the data item's representation) .

Until today, I have purposely not provided the implementation for structures,
forcing the user of the function to provide an implementation for each
structure, for example:

struct S
{
int a;
float b;
double c;
};

template <void reverseEndian(S & s)
{
// Function body -- can this be automated?
reverseEndian<> (s.a);
reverseEndian<> (s.b);
reverseEndian<> (s.c);
}

Is it possible to automatically generate the contents of the specialization?
This calls for introspection (the language feature, not the Zen philosophy),
and so far I have not found any way to do it, portable or otherwise.
I don't know of a means of doing this, when faced with this kind of a
problem, I tend to resort to code generation.

--
Ian Collins.
Feb 18 '07 #2
Dave Rahardja wrote:
Is there a way to generate a series of statements based on the data members of
a structure at compile time?

I have a function that reverses the endianness of any data structure:

/// Reverse the endianness of a data structure "in place".
template <typename T>
void reverseEndian(T &);

Using boost, it is possible to provide the default implementation for all POD
types (i.e. simply reverse the bytes in the data item's representation) .

Until today, I have purposely not provided the implementation for structures,
forcing the user of the function to provide an implementation for each
structure, for example:

struct S
{
int a;
float b;
double c;
};

template <void reverseEndian(S & s)
{
// Function body -- can this be automated?
reverseEndian<> (s.a);
reverseEndian<> (s.b);
reverseEndian<> (s.c);
}

Is it possible to automatically generate the contents of the specialization?
This calls for introspection (the language feature, not the Zen philosophy),
and so far I have not found any way to do it, portable or otherwise.

-dr
There are a lot of ways to do introspection in C++. So far
the most portable one is to use macros. The idea is, as you
define classes you also put plain Macros that expand to code
that will help you do introspection. Here is a quick example:

class A
{
public:
// your regualr C++ goes here
void foo();
int bar;
public:
// introspection via macros
REFLECT_MEM_FUN C( foo, ...... );
REFLECT_MEM_VAR ( bar, ... );
};

But I honestly hate this approach since when I go read a class,
it doubles up the length of the class just because of those
manual introspection lines. Plus it is prone to user error. Like
if you misspelled something or omitted something.

Wouldn't it be cool if you wrote regular C++ and somehow, someway
the C++ language created the necessary data by itself? This is
currently being discussed by the C++ LWG and proposals have been
made. Unfortunately, it will be a while until we get an answer about
this issue since it is still labeled "Open" status by the LWG.

And then there are some talented people who come to the rescue:

http://seal-reflex.web.cern.ch/seal-reflex/

Good Luck!
Feb 19 '07 #3

BTW, on second reading, you wanted to do Compile-time introspection:

I would look into heavy use of template metaprogramming to do this.
If that is too exotic for you, run-time introspection could be a good
alternative for you. (The stuff I originally posted.)

Good Luck!
Piyo wrote:
Dave Rahardja wrote:
>Is there a way to generate a series of statements based on the data
members of
a structure at compile time?

I have a function that reverses the endianness of any data structure:

/// Reverse the endianness of a data structure "in place".
template <typename T>
void reverseEndian(T &);

Using boost, it is possible to provide the default implementation for
all POD
types (i.e. simply reverse the bytes in the data item's representation) .

Until today, I have purposely not provided the implementation for
structures,
forcing the user of the function to provide an implementation for each
structure, for example:

struct S
{
int a;
float b;
double c;
};

template <void reverseEndian(S & s)
{
// Function body -- can this be automated?
reverseEndian<> (s.a);
reverseEndian<> (s.b);
reverseEndian<> (s.c);
}

Is it possible to automatically generate the contents of the
specialization ?
This calls for introspection (the language feature, not the Zen
philosophy),
and so far I have not found any way to do it, portable or otherwise.

-dr

There are a lot of ways to do introspection in C++. So far
the most portable one is to use macros. The idea is, as you
define classes you also put plain Macros that expand to code
that will help you do introspection. Here is a quick example:

class A
{
public:
// your regualr C++ goes here
void foo();
int bar;
public:
// introspection via macros
REFLECT_MEM_FUN C( foo, ...... );
REFLECT_MEM_VAR ( bar, ... );
};

But I honestly hate this approach since when I go read a class,
it doubles up the length of the class just because of those
manual introspection lines. Plus it is prone to user error. Like
if you misspelled something or omitted something.

Wouldn't it be cool if you wrote regular C++ and somehow, someway
the C++ language created the necessary data by itself? This is
currently being discussed by the C++ LWG and proposals have been
made. Unfortunately, it will be a while until we get an answer about
this issue since it is still labeled "Open" status by the LWG.

And then there are some talented people who come to the rescue:

http://seal-reflex.web.cern.ch/seal-reflex/

Good Luck!

Feb 19 '07 #4
On Mon, 19 Feb 2007 01:24:18 GMT, Piyo <cy*********@ya hoo.comwrote:
>
BTW, on second reading, you wanted to do Compile-time introspection:

I would look into heavy use of template metaprogramming to do this.
If that is too exotic for you, run-time introspection could be a good
alternative for you. (The stuff I originally posted.)

Good Luck!
(ignoring top-post faux pas)

I am conversant with template metaprogramming , but still find no way to do
compile-time introspection.

-dr
Feb 19 '07 #5
Piyo wrote:
>
There are a lot of ways to do introspection in C++. So far
the most portable one is to use macros. The idea is, as you
define classes you also put plain Macros that expand to code
that will help you do introspection. Here is a quick example:
I don't think so, not according to the traditional use of the term, to
be able to examine and possibly modify, an object at runtime. This
would permit a serialise function to determine the data members of a
class and automatically serialise them.

In C++, the only alternative is code generation or some form of
meta-compilation.

--
Ian Collins.
Feb 19 '07 #6
Ian Collins wrote:
Piyo wrote:
>There are a lot of ways to do introspection in C++. So far
the most portable one is to use macros. The idea is, as you
define classes you also put plain Macros that expand to code
that will help you do introspection. Here is a quick example:
I don't think so, not according to the traditional use of the term, to
be able to examine and possibly modify, an object at runtime. This
would permit a serialise function to determine the data members of a
class and automatically serialise them.
It depends on how you define introspection. Some only deal with the fact
that at run-time, you would like to be able to determine what are the
member functions and what are the member variables and or types and such
or even what are their superclasses too. From that point of view, if you
only plan on "querying introspection", then macros and Reflex can do
this for you. Please invest the time to go to the website and check it
out for yourself. Based on the macro or Reflex approach, you can write a
serialization function ONCE and then the magic of introspection will
work immediately. I serialize my "Reflexed" classes by first generating
a database schema on the fly and then serialize them to and from the
database. Go to the site and you might be amazed. I have it working in
practice.

If you plan on taking a class and possibly defining its make up at
runtime, you can still also do that (albeit very very ugly IMO) but it
requires a framework of classes and stuff to do so. I believe I did see
one out there. That will satisfy both sides of the equation of
introspection. But for my needs, I did not require a dynamic make up of
a class's structure so I went and used Seal Reflex.
>
In C++, the only alternative is code generation or some form of
meta-compilation.
And that's exactly what Seal does (and macros too since it creates code
for you in a sense). Also, if you check out the C++ LWG, a proposal has
been submitted to address this very issue of introspection in C++ and it
does have a very very good background survey of the state-of-the-art in
this. I just find it sad that the LWG has put it on the backburner.
Feb 19 '07 #7
* Dave Rahardja:
Is there a way to generate a series of statements based on the data members of
a structure at compile time?

I have a function that reverses the endianness of any data structure:

/// Reverse the endianness of a data structure "in place".
template <typename T>
void reverseEndian(T &);

Using boost, it is possible to provide the default implementation for all POD
types (i.e. simply reverse the bytes in the data item's representation) .

Until today, I have purposely not provided the implementation for structures,
forcing the user of the function to provide an implementation for each
structure, for example:

struct S
{
int a;
float b;
double c;
};

template <void reverseEndian(S & s)
{
// Function body -- can this be automated?
reverseEndian<> (s.a);
reverseEndian<> (s.b);
reverseEndian<> (s.c);
}

Is it possible to automatically generate the contents of the specialization?
This calls for introspection (the language feature, not the Zen philosophy),
and so far I have not found any way to do it, portable or otherwise.
No, you can't do what you want directly, at least as of the current
standard.

But yes, there other ways.

One way is to note that if you could serialize and deserialize the
object, then you could do the processing in between those two steps. So
your problem is essentially equivalent to the serialization problem,
suggesting you look at Boost facilities for serialization, and require
"serializabilit y" for the classes. Or even simpler, require "dumb
serialization" support: dump fields into vector, read 'em back from a
vector. After all you don't need more.

Another way is to do code generation. Of course that's also one
approach to serialization, for the same reasons. I regret to say that I
don't know very much about current tools, except that I think there's a
more or less complete C++ parser at SourgeForge (you could look into
building your own e.g. using Boost Phoenix, but it's a daunting task!).
What I can tell you of direct experience is that the g++ source code,
otherwise a natural starting point for build-your-own, is very complex.
And it's K&R C...

A third way is to note that your problem is very specialized compared to
general serialization. You're not interested in arbitrary structures,
only simple PODs. Thus, if you could define some simple descriptor,
then perhaps that would be acceptable for client code. One example of a
descriptor sufficient for your needs would be a list of offsets for the
fields in the struct, with a final offset just past the final field. I
think this would be my method of choice: not especially type safe, but
solving the practical problem at hand (perhaps the Boost preprocessor
facilities could be of help in automating descriptor generation).

Hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 19 '07 #8
Piyo wrote:
Ian Collins wrote:
>Piyo wrote:
>>There are a lot of ways to do introspection in C++. So far
the most portable one is to use macros. The idea is, as you
define classes you also put plain Macros that expand to code
that will help you do introspection. Here is a quick example:
I don't think so, not according to the traditional use of the term, to
be able to examine and possibly modify, an object at runtime. This
would permit a serialise function to determine the data members of a
class and automatically serialise them.


It depends on how you define introspection. Some only deal with the fact
that at run-time, you would like to be able to determine what are the
member functions and what are the member variables and or types and such
or even what are their superclasses too. From that point of view, if you
only plan on "querying introspection", then macros and Reflex can do
this for you. Please invest the time to go to the website and check it
out for yourself.
It looks interesting, but my development environment isn't supported :(

--
Ian Collins.
Feb 19 '07 #9
Dave Rahardja wrote:
On Mon, 19 Feb 2007 01:24:18 GMT, Piyo <cy*********@ya hoo.comwrote:
>BTW, on second reading, you wanted to do Compile-time introspection:

I would look into heavy use of template metaprogramming to do this.
If that is too exotic for you, run-time introspection could be a good
alternative for you. (The stuff I originally posted.)

Good Luck!

(ignoring top-post faux pas)

I am conversant with template metaprogramming , but still find no way to do
compile-time introspection.

-dr
Is there a problem with run-time introspection? Because, based on your
previous example, you can do this.

// note I am making up the syntax for Seal Reflex since I don't have
// access to my work code right now. But I assure you, this can be done.
class ReflectedClass
{
public:
ReflectedClass( )
{
MemberVar::iter ator iter =
Reflex::Class(" ReflectedClass" ).getMemberVars ().begin();
MemberVar::iter ator end =
Reflex::Class(" ReflectedClass" ).getMemberVars ().end();
for( ; iter!=end; ++iter )
{
// I just realized that you need to be careful since
// if it returns a non-POD, you need to recursively apply
// this function.
reverseEndian( iter->getVar() );
}
}

public:
int a;
float b;
double c;
// now later on, you can add as many member vars and you do not
// need to change the constructor at all.
};

If you don't like the constructor approach, your template function
will look like this:

template <typename Svoid reverseEndian(S & s)
{
// Reflex can take in a type I believe instead of a string
// for the Class constructor. Not sure. please check Seal docs.
// but hopefully you can go from Type to "name" via template
// type functions like show below.
MemberVar::iter ator iter =
Reflex::Class(T ypeMapper<S>::t heName).getMemb erVars().begin( );
MemberVar::iter ator end =
Reflex::Class(T ypeMapper<S>::t heName).getMemb erVars().end();
for( ; iter!=end; ++iter )
{
// same warning as above applies
reverseEndianPO D( iter->getVar() );
}

}
Feb 19 '07 #10

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

Similar topics

8
2807
by: janeaustine50 | last post by:
Python's InteractiveInterpreter uses the built-in compile function. According to the ref. manual, it doesn't seem to concern about the encoding of the source string. When I hand in an unicode object, it is encoded in utf-8 automatically. It can be a problem when I'm building an interactive environment using "compile", with a different encoding from utf-8. IDLE itself has the same problem. ( '<a string with non-ascii-encoding>' is...
1
4454
by: Mario T. Lanza | last post by:
I am working with Visual Studio. The solution I am developing is composed of about 8 separate projects. Some of these projects represent different tiers in the N-tiered architecture (data, business logic, presentation, etc.). Right now, some of the projects are inter-related and reference each other using Project References. When I select "Rebuild Solution" to compile, each project is successfully compiled into its own directory (and...
4
3256
by: frankg | last post by:
When I compile this file ------------------------------------------------------ #include <stdarg.h> template <class Any> void var_arg_func(int dimension_count, ...) { int dimensions; va_list ap;
0
2627
by: Jordan Willms | last post by:
My xsl stylesheet is as simple as follows: <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet xmlns:ims="http://www.imsglobal.org/xsd/imsmd_v1p2" xmlns="http://ltsc.ieee.org/xsd/LOMv1p0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/> <!-- rename ims datetime tags to IEEE dateTime tags --> <xsl:template match="ims:datetime">
6
2844
by: Thomas Connolly | last post by:
I have 2 pages referencing the same codebehind file in my project. Originally the pages referenced separate code behind files. Once I changed the reference to the same file, everything worked fine while the file was in the project directory. When the obsolete file was removed from the project directory, my application will no longer compile. Can someone please help with this issue? Thank in advance, Tom
4
1835
by: tony | last post by:
Hello! My question is about calling this method CollectData below but I get a compile error that I shouldn't have because the type parameter is correct. The compile error is the following: C:\PK\Development\Products\UTCAS\4.0\SRC\MeltPracApplication\Dialog\Composit ionForm.cs(942): Argument '1': cannot convert from 'ref MeltPracData.MeltPracDataComposition' to 'ref MeltPracCommon.IDialogPostData'
1
3071
by: brianrpsgt1 | last post by:
Newbie here.... I have been able to successful pull info from a MySQL DB, get the results and output them in an HTML format using Cheetah to the screen using IDLE. I am doing this on a Windows Laptop, running WinXP, Python 2.5 and the latest version of Cheetah. I have two questions: 1. How and where do you compile Cheetah templates in Windows? The command in the docs is cheetah compile a, however, I believe that this
3
2291
by: NvrBst | last post by:
Right now I have C99 code in .c extensions. I compile it in VSC++ and it complains about a lot of errors. I change the extensions to .cpp and compile in VSC++ and it succeeds. Is there a way to keep my extensions .c, but tell VSC++ (through an project option) to compile as C++98 code (as if it had .cpp extensions).
2
6915
by: Andrus | last post by:
I need compile in-memory assembly which references to other in-memory assembly. Compiling second assembly fails with error Line: 0 - Metadata file 'eed7li9m, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' could not be found Saving assembly to Windows temp directory for referencing only creates huge amout of temporary
6
1938
by: Ed Leafe | last post by:
I've noticed an odd behavior with compile() and code that does not contain a trailing newline: if the last line is a comment inside of any block, a syntax error is thrown, but if the last line is a non- comment Python statement, there is no error. Here's an example (using 2.5.1 on OS X) .... def foo(): .... print 'bar' """ <code object <moduleat 0x79608, file "", line 2>
0
8182
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
8627
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...
0
8579
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8279
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
8433
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6088
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
5540
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();...
1
1747
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1425
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.