Topic: for each member of a sturcture/class ?
Author: x@y.z (Martijn Meijering)
Date: Thu, 20 Dec 2007 21:44:00 GMT Raw View
Roman.Perepelitsa@gmail.com wrote:
> Yes, it works as is; there is no need for additional commas. And yes,
> macro arguments can span multiple lines.
Cool, thanks!
> Yes, sometimes I resort to use preprocessor metaprogramming.
> It's ugly, Intellisense unfriendly, but it could be better than other
> solutions in some cases.
Agreed.
> By the way, boost itself heavily uses preprocessor
> metaprogramming. In C++0X most of it will go away, but at the
> moment you either have to copy-pase large chunks of code,
> use preprocessor or generate code with the help of external tool.
>
>
>>It seems to me that we aren't very far removed from what needs to be
>>done to do this sort of thing without boost.
>
>
> Without boost it's way harder. Note that fusion::for_each is not the
> only
> algorithm you can use with 'asset' structure. There are plenty of
> useful
> algorithms in fusion and 'asset' is compatible with them.
Sounds like something I need to study more closely!
>>If type lists were added to typeinfo, wouldn't that do the trick?
>
>
> Lists added to typeinfo? What do you mean?
Oops, it seems I meant type_info, I guess it shows that I don't use it
very often :-)
I meant that type_info seems like the right place to store detailed
information about types. If I'm not mistaken, about all it does now is
generate an implementation-defined string representation and allow
instances of type_info to be compared for equality.
For persistance, serialisation etc you'd want to be able to loop over
all members and for each member be able to fetch a pointer to member.
With that pointer you could retrieve a value from an instance of the
type and write it to a stream or something. This isn't really a
typelist, but more a list of pairs of strings and function pointers.
I don't think you can fit this information into a fixed data structure
such as the type type_info. What you could do is have the compiler
generate a new subclass of type_info for every type whose typeinfo you
retrieve with typeid.
I was thinking that if we give type_info a virtual member ForEach, we
could use it to loop over the elements of the type and do something
appropriate. Now that I think more closely about it, I think that would
require a combination of member templates and virtual functions, which
is not possible at present and unlikely to be in future. Maybe you could
do something with decltype. Or maybe it is harder than I think.
I guess I'm just wondering how difficult it would be to add proper
reflection to C++. It would be nice if you could pass a templatised
closure to type_info.ForEach... How far do you think we are away from this?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: restor <akrzemi1@interia.pl>
Date: Thu, 20 Dec 2007 15:45:05 CST Raw View
Hi all,
I am not very good at C++ metaprogramming, so what I say may be wrong,
but it seams that C++0x is getting close to compile-time "reflection".
Type traits library already requires impemntations to provide
information such as has_nothrow_copy_constructor. Would it not be
relatively easy to implement yet another trait: tuple_representation,
which would expose a tuple interface to any struct/class? Tuples can
be iterated over at compile time, so defining common operations for
all members would be fairly easy.
Of course access specifiers would have to be respected, so there would
have to be a trickery like:
class CC{
public: int i;
private: double x;
};
CC c = { 1, 0.5 };
std::tuple_representation<CC> & ccTuple =
std::tuple_representation(cc);
ccTuple.get<0>(); // ok, return 1
ccTuple.get<1>(); // error: function
"std::tuple_representation::get<1>()" is private.
Would it be feasible?
Andrzej Krzemienski
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: german diago <germandiago@gmail.com>
Date: Sat, 22 Dec 2007 09:12:02 CST Raw View
On 17 dic, 17:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
> One thing that would help me a lot in code would be something that allowed
> me to iterate through the members of a class or structure. Consider
> serialization.
>
> To serialize a class or structure I need to serialze each type (not hard)
> then in the class serialize each variable. For a simple structure, such as
> holding integers and std::strings, if there was some way to iterate through
> the variables it would be simple something like in pseudo code:
>
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
>
> }
>
> There is also a case where I want to tie a structure/class into a database
> and need to go through each variable and call a function to tie it in, a
> simple thing if there was a way to call something for each variable.
>
> I can't even think how to try to do this in C++ currently.
>
> --
> Jim Langston
> tazmas...@rocketmail.com
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
I was working in a library for serialization, and I tried my best to
write the minimal amount of code
to serialize an object. The library is not finished yet, but what I
have now is something like this:
/This type is similar to a tuple, but holds pointers
template <class... Args>
class DataSerializer {...};
class MyClass
{
public:
typedef DataSerializer<int, float> serialization_data;
private:
int a;
float c;
public:
SerialData data(){ return serialization_data(a, c); }
};
Now we have a save() and restore() function for obects. It's a
function template that saves or restores data.
As long as a type has a specialization of Serializable concept, the
type can be serialized. Built-in types are
serializable by default.
And if you have, for example, MyClass inside another class and MyClass
is serializable because you wrote
its requirements to meet the conept,:
class AnotherClass
{
int a;
string b;
//MyClass meets serializable concept
MyClass m;
typedef SerialData<int, string, MyClass> serial_data;
serial_data data() { return serial_data(a, b, m); }
};
Now you have, for example:
AnotherClass c;
save(c, myfile);
save is a generic algorithm that can serialize serializable types, as
long as they meet requirements.
So with minimal code, you can serialize data. Next things are pointers
and stl containers.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Mon, 24 Dec 2007 20:11:16 CST Raw View
On 21 Dec, 00:44, x...@y.z (Martijn Meijering) wrote:
> I meant that type_info seems like the right place to store detailed
> information about types. If I'm not mistaken, about all it does now is
> generate an implementation-defined string representation and allow
> instances of type_info to be compared for equality.
>
> For persistance, serialisation etc you'd want to be able to loop over
> all members and for each member be able to fetch a pointer to member.
> With that pointer you could retrieve a value from an instance of the
> type and write it to a stream or something. This isn't really a
> typelist, but more a list of pairs of strings and function pointers.
>
> I don't think you can fit this information into a fixed data structure
> such as the type type_info. What you could do is have the compiler
> generate a new subclass of type_info for every type whose typeinfo you
> retrieve with typeid.
>
> I was thinking that if we give type_info a virtual member ForEach, we
> could use it to loop over the elements of the type and do something
> appropriate. Now that I think more closely about it, I think that would
> require a combination of member templates and virtual functions, which
> is not possible at present and unlikely to be in future. Maybe you could
> do something with decltype. Or maybe it is harder than I think.
>
> I guess I'm just wondering how difficult it would be to add proper
> reflection to C++. It would be nice if you could pass a templatised
> closure to type_info.ForEach... How far do you think we are away from this?
I don't think it is a way to go. Runtime reflection adds
runtime overhead, which is hard to eliminate. On the
other hand, compile time reflection has no impact
on performance or memory usage and also it can be
easily converted to runtime reflection by providing
OO wrappers. What would be really useful is something
like restor suggested in this thread: ability to get tuple
of references to all members of a struct/class. But
I'm not aware of any proposals regarding this subject.
Regards,
Roman Perepelitsa.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: x@y.z (Martijn Meijering)
Date: Fri, 28 Dec 2007 18:44:07 GMT Raw View
Roman.Perepelitsa@gmail.com wrote:
> I don't think it is a way to go. Runtime reflection adds
> runtime overhead, which is hard to eliminate. On the
> other hand, compile time reflection has no impact
> on performance or memory usage and also it can be
> easily converted to runtime reflection by providing
> OO wrappers.
Sure, I was thinking of compile-time reflection, which is why I would
like to be able to pass in a templated block to ForEach.
> What would be really useful is something
> like restor suggested in this thread: ability to get tuple
> of references to all members of a struct/class.
Agreed.
>But
> I'm not aware of any proposals regarding this subject.
Neither am I, but I think it would be quite an important addition. Not
quite as important as modules, but still quite important.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: coal@mailvault.com
Date: Tue, 1 Jan 2008 03:21:37 CST Raw View
On Dec 22, 9:12 am, german diago <germandi...@gmail.com> wrote:
> On 17 dic, 17:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
>
>
>
>
>
> > One thing that would help me a lot in code would be something that allowed
> > me to iterate through the members of a class or structure. Consider
> > serialization.
>
> > To serialize a class or structure I need to serialze each type (not hard)
> > then in the class serialize each variable. For a simple structure, such as
> > holding integers and std::strings, if there was some way to iterate through
> > the variables it would be simple something like in pseudo code:
>
> > std::ostream& operator<<( std::ostream& os)
> > {
> > for_each_member( os << member );
>
> > }
>
> > There is also a case where I want to tie a structure/class into a database
> > and need to go through each variable and call a function to tie it in, a
> > simple thing if there was a way to call something for each variable.
>
> > I can't even think how to try to do this in C++ currently.
>
> > --
> > Jim Langston
> > tazmas...@rocketmail.com
>
> > ---
> > [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> > [ your news-reader. If that fails, use mailto:std-...@ncar.ucar.edu ]
> > [ --- Please see the FAQ before posting. --- ]
> > [ FAQ:http://www.comeaucomputing.com/csc/faq.html ]
>
> I was working in a library for serialization, and I tried my best to
> write the minimal amount of code
> to serialize an object. The library is not finished yet, but what I
> have now is something like this:
>
> /This type is similar to a tuple, but holds pointers
> template <class... Args>
> class DataSerializer {...};
>
> class MyClass
> {
> public:
> typedef DataSerializer<int, float> serialization_data;
>
> private:
> int a;
> float c;
>
> public:
> SerialData data(){ return serialization_data(a, c); }
>
> };
>
> Now we have a save() and restore() function for obects. It's a
> function template that saves or restores data.
> As long as a type has a specialization of Serializable concept, the
> type can be serialized. Built-in types are
> serializable by default.
> And if you have, for example, MyClass inside another class and MyClass
> is serializable because you wrote
> its requirements to meet the conept,:
>
> class AnotherClass
> {
> int a;
> string b;
>
> //MyClass meets serializable concept
> MyClass m;
>
> typedef SerialData<int, string, MyClass> serial_data;
>
> serial_data data() { return serial_data(a, b, m); }
>
> };
I don't think you read the original post or his followup very closely.
He wants to avoid duplicating the types and names.
>
> Now you have, for example:
>
> AnotherClass c;
> save(c, myfile);
>
> save is a generic algorithm that can serialize serializable types, as
> long as they meet requirements.
> So with minimal code, you can serialize data. Next things are pointers
> and stl containers.
>
What is your rationale for this library? Have you done any
performance
tests with your stuff? There are a few between Boost serialization
and our
approach here - www.webebenezer.net. I think it makes sense for those
who are taking the library approach to work together. Right now you
are duplicating more than just decarations.
Brian Wood
Ebenezer Enterprises
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Wed, 2 Jan 2008 00:08:20 CST Raw View
On 12/20/07 15:44, Martijn Meijering wrote:
[snip]
> I was thinking that if we give type_info a virtual member ForEach, we
> could use it to loop over the elements of the type and do something
> appropriate. Now that I think more closely about it, I think that would
> require a combination of member templates and virtual functions, which
> is not possible at present and unlikely to be in future. Maybe you could
> do something with decltype. Or maybe it is harder than I think.
>
> I guess I'm just wondering how difficult it would be to add proper
> reflection to C++. It would be nice if you could pass a templatised
> closure to type_info.ForEach... How far do you think we are away from this?
The boost visit_each *may* provide you with more implementation clues:
http://www.boost.org/doc/html/boost/visit_each.html
quoting from there:
The visit_each mechanism allows a visitor to be applied to every
subobject in a given object.
HTH.
-regards,
Larry
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Tue, 18 Dec 2007 01:19:08 CST Raw View
On 17 d c, 17:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
>
> }
> [...]
>
> I can't even think how to try to do this in C++ currently.
Make a type list of function object types with all your members and
simply iterate it.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Tue, 18 Dec 2007 08:51:48 CST Raw View
On 17 Dec, 19:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
> One thing that would help me a lot in code would be something that allowed
> me to iterate through the members of a class or structure. Consider
> serialization.
>
> To serialize a class or structure I need to serialze each type (not hard)
> then in the class serialize each variable. For a simple structure, such as
> holding integers and std::strings, if there was some way to iterate through
> the variables it would be simple something like in pseudo code:
>
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
>
> }
>
> There is also a case where I want to tie a structure/class into a database
> and need to go through each variable and call a function to tie it in, a
> simple thing if there was a way to call something for each variable.
>
> I can't even think how to try to do this in C++ currently.
>
> --
> Jim Langston
> tazmas...@rocketmail.com
Take a look at boost::fusion. There are algorithms for iteration,
transformation and so on, which you can use against fields
of your structure after adapting it with
BOOST_FUSION_ADAPT_STRUCT macros.
#include <iostream>
#include <string>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
using namespace std;
using namespace boost;
// structure, which fields you'd like to iterate
struct asset
{
string name;
double price;
};
// it makes asset a fusion sequence
// you can use fusion algorithms against asset
BOOST_FUSION_ADAPT_STRUCT(asset,
(string, name)
(double, price)
)
struct print
{
print(ostream & strm) : m_strm(strm) {}
template <class T>
void operator()(const T & val) const
{
m_strm << val << endl;
}
private:
ostream & m_strm;
};
ostream & operator<<(ostream & strm, const asset & as)
{
// iterate over all fields of asset and print each of them
fusion::for_each(as, print(strm));
return strm;
}
int main(int argc, char * argv[])
{
asset as = { "book", 49.99 };
cout << as << endl;
}
Regards,
Roman Perepelitsa.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Tue, 18 Dec 2007 10:58:02 CST Raw View
On 17 Dec, 19:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
> One thing that would help me a lot in code would be something that allowed
> me to iterate through the members of a class or structure. Consider
> serialization.
>
> To serialize a class or structure I need to serialze each type (not hard)
> then in the class serialize each variable. For a simple structure, such as
> holding integers and std::strings, if there was some way to iterate through
> the variables it would be simple something like in pseudo code:
>
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
>
> }
>
> There is also a case where I want to tie a structure/class into a database
> and need to go through each variable and call a function to tie it in, a
> simple thing if there was a way to call something for each variable.
>
> I can't even think how to try to do this in C++ currently.
>
> --
> Jim Langston
> tazmas...@rocketmail.com
Take a look at boost::fusion. There are algorithms for iteration,
transformation and so on, which you can use against fields
of your structure after adapting it with
BOOST_FUSION_ADAPT_STRUCT macros.
#include <iostream>
#include <string>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
using namespace std;
using namespace boost;
// structure, which fields you'd like to iterate
struct asset
{
string name;
double price;
};
// it makes asset a fusion sequence
// you can use fusion algorithms against asset
BOOST_FUSION_ADAPT_STRUCT(asset,
(string, name)
(double, price)
)
struct print
{
print(ostream & strm) : m_strm(strm) {}
template <class T>
void operator()(const T & val) const
{
m_strm << val << endl;
}
private:
ostream & m_strm;
};
ostream & operator<<(ostream & strm, const asset & as)
{
// iterate over all fields of asset and print each of them
fusion::for_each(as, print(strm));
return strm;
}
int main(int argc, char * argv[])
{
asset as = { "book", 49.99 };
cout << as << endl;
}
Regards,
Roman Perepelitsa.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Jim Langston" <tazmaster@rocketmail.com>
Date: Tue, 18 Dec 2007 12:07:45 CST Raw View
"Jim Langston" wrote:
> One thing that would help me a lot in code would be something that
> allowed me to iterate through the members of a class or structure.
> Consider serialization.
>
> To serialize a class or structure I need to serialze each type (not
> hard) then in the class serialize each variable. For a simple
> structure, such as holding integers and std::strings, if there was
> some way to iterate through the variables it would be simple
> something like in pseudo code:
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
> }
>
> There is also a case where I want to tie a structure/class into a
> database and need to go through each variable and call a function to
> tie it in, a simple thing if there was a way to call something for
> each variable.
> I can't even think how to try to do this in C++ currently.
Looking at both boost::fustion and boost serialization they are doing the
exact thing I don't want to do, list each member of the structure twice.
Once in the class declaration, once in some other function/method. That I
can already do in my code which is what I'm trying to prevent.
C++ does nto currently have a way to do it, it's not part of the language.
--
Jim Langston
tazmaster@rocketmail.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: x@y.z (Martijn Meijering)
Date: Tue, 18 Dec 2007 19:30:16 GMT Raw View
Jim Langston wrote:
> Looking at both boost::fustion and boost serialization they are doing the
> exact thing I don't want to do, list each member of the structure twice.
> Once in the class declaration, once in some other function/method. That I
> can already do in my code which is what I'm trying to prevent.
I'm not familiar with boost::fusion, but I agree with your goal to
eliminate duplication. Once And Only Once, Don't Repeat Yourself. It's a
pity boost::fusion apparently doesn't allow you to do that.
> C++ does nto currently have a way to do it, it's not part of the language.
If you /really/ want to do it, you can do it with preprocessor
meta-programming, at the cost of using macro's to declare member variables.
With a lot of work (and a lot of peeking at the boost preprocessor
library) I was able to write a macro DECLARE_FIELDS that allows you to
write this:
class Pipo
{
public:
DECLARE_FIELDS
(
((int,a))
((string,b))
)
};
and get enough meta-information to allow you to implement a ForEach
member function template that you can use as follows:
class Op
{
public:
template<class T>
void operator()(const T& t) const
{
// cout << t << endl;
}
};
void TestForEach()
{
Pipo pipo;
Op op;
pipo.ForEach(op);
}
I'm not really sure this is conforming code, in particular whether the
argument list to DECLARE_FIELDS is allowed to span multiple lines. FWIW,
it does compile with Visual Studio 6.0.
Writing such code is an interesting challenge, but it feels really wrong
that we should need to do something so complicated as this to something
as essential as eliminating redundancy.
Ideally it should be possible to do this within the language itself. If
we have to resort to using the preprocessor it would help a lot if we
actually had a decent preprocessor, instead of the brain-dead
preprocessor we have today.
I would rather see it done in the language itself, but realistically,
it's going to be long time before C++ has evolved enough to make most of
the subtle trickery in boost unnecessary. In the meantime it would help
a lot if we had a decent preprocessor. It seems to me that it wouldn't
be too difficult to add functionality to the preprocessor that
eliminates most of the trickery in the boost preprocessor
metaprogramming library. I'm thinking of if's and for's, overloading and
recursion. We are already getting variadic macro's.
But perhaps things are more subtle than I think. I wonder what the
experts think about this.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Wed, 19 Dec 2007 11:09:24 CST Raw View
On 18 Dec, 21:07, "Jim Langston" <tazmas...@rocketmail.com> wrote:
> Looking at both boost::fustion and boost serialization they are doing the
> exact thing I don't want to do, list each member of the structure twice.
> Once in the class declaration, once in some other function/method. That I
> can already do in my code which is what I'm trying to prevent.
>
> C++ does nto currently have a way to do it, it's not part of the language.
As Martijn Meijering mentioned, you can do it using preprocessor. Note
the use of DECLARE_STRUCT macro, which shows how you can declare
struct without specifying each field twice.
#include <iostream>
#include <string>
#include <boost/preprocessor.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#define DEFINE_STRUCT(name, fields) \
DEFINE_STRUCT_I(name, \
BOOST_PP_CAT(DEFINE_STRUCT_X fields, 0))
#define DEFINE_STRUCT_X(x, y) ((x, y)) DEFINE_STRUCT_Y
#define DEFINE_STRUCT_Y(x, y) ((x, y)) DEFINE_STRUCT_X
#define DEFINE_STRUCT_X0
#define DEFINE_STRUCT_Y0
#define DEFINE_STRUCT_I(name, fields) \
struct name \
{ \
BOOST_PP_SEQ_FOR_EACH_I \
(DEFINE_STRUCT_FIELD, _, fields) \
}; \
BOOST_FUSION_ADAPT_STRUCT_I(name, fields)
#define DEFINE_STRUCT_FIELD(r, _, i, xy) \
BOOST_PP_TUPLE_ELEM(2, 0, xy) \
BOOST_PP_TUPLE_ELEM(2, 1, xy);
using namespace std;
using namespace boost;
DEFINE_STRUCT(asset,
(string, name)
(double, price)
)
struct print
{
print(ostream & strm) : m_strm(strm) {}
template <class T>
void operator()(const T & val) const
{
m_strm << val << endl;
}
private:
ostream & m_strm;
};
ostream & operator<<(ostream & strm, const asset & as)
{
fusion::for_each(as, print(strm));
return strm;
}
int main(int argc, char * argv[])
{
asset as = { "book", 49.99 };
cout << as << endl;
}
Regards,
Roman Perepelitsa.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: x@y.z (Martijn Meijering)
Date: Wed, 19 Dec 2007 17:32:18 GMT Raw View
Roman.Perepelitsa@gmail.com wrote:
> As Martijn Meijering mentioned, you can do it using preprocessor. Note
> the use of DECLARE_STRUCT macro, which shows how you can declare
> struct without specifying each field twice.
[snip]
> DEFINE_STRUCT(asset,
> (string, name)
> (double, price)
> )
Nice.
Is there a comma missing after (string, name) or does it work as is?
Your example suggests that you are in fact allowed to have macro
arguments span multiple lines, something I wasn't sure of. Can anyone
confirm this is the case?
And is this something you would use in production code? I imagine it
confuses things like Intellisense, which would be a pity.
It seems to me that we aren't very far removed from what needs to be
done to do this sort of thing without boost. If type lists were added to
typeinfo, wouldn't that do the trick?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Roman.Perepelitsa@gmail.com" <Roman.Perepelitsa@gmail.com>
Date: Thu, 20 Dec 2007 11:28:36 CST Raw View
On 19 Dec, 20:32, x...@y.z (Martijn Meijering) wrote:
> > DEFINE_STRUCT(asset,
> > (string, name)
> > (double, price)
> > )
>
> Nice.
>
> Is there a comma missing after (string, name) or does it work as is?
> Your example suggests that you are in fact allowed to have macro
> arguments span multiple lines, something I wasn't sure of. Can anyone
> confirm this is the case?
Yes, it works as is; there is no need for additional commas. And yes,
macro arguments can span multiple lines.
> And is this something you would use in production code? I imagine it
> confuses things like Intellisense, which would be a pity.
Yes, sometimes I resort to use preprocessor metaprogramming.
It's ugly, Intellisense unfriendly, but it could be better than other
solutions in some cases.
By the way, boost itself heavily uses preprocessor
metaprogramming. In C++0X most of it will go away, but at the
moment you either have to copy-pase large chunks of code,
use preprocessor or generate code with the help of external tool.
> It seems to me that we aren't very far removed from what needs to be
> done to do this sort of thing without boost.
Without boost it's way harder. Note that fusion::for_each is not the
only
algorithm you can use with 'asset' structure. There are plenty of
useful
algorithms in fusion and 'asset' is compatible with them.
> If type lists were added to typeinfo, wouldn't that do the trick?
Lists added to typeinfo? What do you mean?
Regards,
Roman Perepelitsa.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: tazmaster@rocketmail.com ("Jim Langston")
Date: Mon, 17 Dec 2007 16:19:22 GMT Raw View
One thing that would help me a lot in code would be something that allowed
me to iterate through the members of a class or structure. Consider
serialization.
To serialize a class or structure I need to serialze each type (not hard)
then in the class serialize each variable. For a simple structure, such as
holding integers and std::strings, if there was some way to iterate through
the variables it would be simple something like in pseudo code:
std::ostream& operator<<( std::ostream& os)
{
for_each_member( os << member );
}
There is also a case where I want to tie a structure/class into a database
and need to go through each variable and call a function to tie it in, a
simple thing if there was a way to call something for each variable.
I can't even think how to try to do this in C++ currently.
--
Jim Langston
tazmaster@rocketmail.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "hhsaez@gmail.com" <hhsaez@gmail.com>
Date: Mon, 17 Dec 2007 10:58:43 CST Raw View
On 17 Dec, 13:19, tazmas...@rocketmail.com ("Jim Langston") wrote:
> One thing that would help me a lot in code would be something that allowed
> me to iterate through the members of a class or structure. Consider
> serialization.
What you need is something like reflection, which is not possible in C+
+.
>
> To serialize a class or structure I need to serialze each type (not hard)
> then in the class serialize each variable. For a simple structure, such as
> holding integers and std::strings, if there was some way to iterate through
> the variables it would be simple something like in pseudo code:
>
> std::ostream& operator<<( std::ostream& os)
> {
> for_each_member( os << member );
>
> }
>
> There is also a case where I want to tie a structure/class into a database
> and need to go through each variable and call a function to tie it in, a
> simple thing if there was a way to call something for each variable.
>
> I can't even think how to try to do this in C++ currently.
>
Overloading the << operator seems to be the best way. Although it
requires some maintenance in the class itself, it hides the actual
implementation from the clients of the class.
Best,
Hernan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Mon, 17 Dec 2007 12:38:08 CST Raw View
On 12/17/07 10:19, Jim Langston wrote:
[snip]
> To serialize a class or structure I need to serialze each type (not hard)
> then in the class serialize each variable.
[snip]
> There is also a case where I want to tie a structure/class into a database
> and need to go through each variable and call a function to tie it in, a
> simple thing if there was a way to call something for each variable.
Boost has a serialization library from which you might get some ideas:
http://www.boost.org/libs/serialization/doc/index.html
There was also some posts about database interfaces here:
http://archives.free.net.ph/message/20061205.092349.9e2ebf91.en.html
HTH
-Larry
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]