mpl related question
Hello mpl experts, I'm trying to initialize the elements of an array using rules defined in a list of structures. The code below illustrate what I'm trying to achieve. The problem I have with this code is that the First_Descriptor structure contain this index member that will be used to access the right item of the array. This is not nice because it force the writer of this structure to deal with implementation details. Is there a way to get rid of this index typedef in the *_Descriptor structures by using another construct from the mpl that would generate it ? // The array I need to initialize. Array_Item array[2]; struct Initializer { template < typename U > void operator()( mpl::identity< U > ) { // This is where array elements are initialized. // Note how the index member is used. array[U::index::type::value].some_method( U::a_param ) ; } } ; // This is one structure containing rules used to initialize array items. struct First_Descriptor { enum { a_param = 123456 } ; typedef mpl::int_< 0 > index ; } ; struct Second_Descriptor { enum { a_param = 2567 } ; typedef mpl::int_< 1 > index ; } ; // The list of structures containg rules to be applied during array // initialization. typedef mpl::list< First_Descriptor, Second_Descriptor > Descriptors ; // traverse the list and apply the rules. mpl::for_each< Descriptors, mpl::make_identity<_> >( Initializer( ) ) ; Thanks for any help you could provide. Istvan
Istvan Buki
Hello mpl experts,
I'm trying to initialize the elements of an array using rules defined in a list of structures. The code below illustrate what I'm trying to achieve.
The problem I have with this code is that the First_Descriptor structure contain this index member that will be used to access the right item of the array. This is not nice because it force the writer of this structure to deal with implementation details. Is there a way to get rid of this index typedef in the *_Descriptor structures by using another construct from the mpl that would generate it ?
The easiest thing to do is just to embed the index as a data member in the Initializer object, which can be stateful. Just bump the index each time the Initializer is invoked. HTH, Dave -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
Hello David, thanks for your clean and simple answer. I also thought about something similar to your answer but I was wondering if there exist some way to calculate that index at compile-time. Looking at the assembly code generated, it doesn't make a big difference to my version where the index values are hard-coded but still... In fact, the question I'm really trying to answer is: what is the price to pay (in term of performance and space) for using an mpl based solution compared to have my array elements initialized by a totally hard-coded function? Up to now what I've found is that my executable is 10% larger and the code is about 4 times slower (again by looking at the assembly code generated). So, if you can think of a more efficient solution I'm still interested. Thanks, Istvan On Monday 26 July 2004 03:36, David Abrahams wrote:
Istvan Buki
writes: Hello mpl experts,
I'm trying to initialize the elements of an array using rules defined in a list of structures. The code below illustrate what I'm trying to achieve.
The problem I have with this code is that the First_Descriptor structure contain this index member that will be used to access the right item of the array. This is not nice because it force the writer of this structure to deal with implementation details. Is there a way to get rid of this index typedef in the *_Descriptor structures by using another construct from the mpl that would generate it ?
The easiest thing to do is just to embed the index as a data member in the Initializer object, which can be stateful. Just bump the index each time the Initializer is invoked.
HTH, Dave
Istvan Buki
Hello David,
thanks for your clean and simple answer. I also thought about something similar to your answer but I was wondering if there exist some way to calculate that index at compile-time.
Yes there is.
Looking at the assembly code generated, it doesn't make a big difference to my version where the index values are hard-coded but still... In fact, the question I'm really trying to answer is: what is the price to pay (in term of performance and space) for using an mpl based solution compared to have my array elements initialized by a totally hard-coded function? Up to now what I've found is that my executable is 10% larger and the code is about 4 times slower (again by looking at the assembly code generated).
Have you got all optimizations enabled with full inlining? What compiler are you using?
So, if you can think of a more efficient solution I'm still interested.
You could use mpl::zip_view< mpl::vector2< mpl::range_c<0, mpl::size<Descriptors>::value> , Descriptors >
as the sequence in your for_each; then each element would contain a compile-time index and a descriptor. HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
I modified my sample code to take advantage of your suggestion to calculate the index at compile time. It works perfectly well and the code generated is faster than my previous version but I still have questions: 1) I'm not sure if this is the right place to ask, if not somebody will certainly be able to point me into the right direction. In the assembly code generated (file attached to this mail), there are two 'call' instructions that seem useless to me. Why not inline the single 'movl' instruction executed as the result of the call? I'm using g++ 3.3.3 with O2 optimization flag and it is probably a very compiler-specific question but perhaps I'm missing something obvious here. 2) By now you probably guessed that my goal is to produce code for embedded use. In this environment standard libraries would not be available. Could you give me some idea how hard it would be to modify the mpl library not to rely on any standard include and lib? Any pointer on where to start are welcome. Thank you for your help, Istvan On Tuesday 03 August 2004 13:56, David Abrahams wrote:
Istvan Buki
writes: Hello David,
thanks for your clean and simple answer. I also thought about something similar to your answer but I was wondering if there exist some way to calculate that index at compile-time.
Yes there is.
Looking at the assembly code generated, it doesn't make a big difference to my version where the index values are hard-coded but still... In fact, the question I'm really trying to answer is: what is the price to pay (in term of performance and space) for using an mpl based solution compared to have my array elements initialized by a totally hard-coded function? Up to now what I've found is that my executable is 10% larger and the code is about 4 times slower (again by looking at the assembly code generated).
Have you got all optimizations enabled with full inlining? What compiler are you using?
So, if you can think of a more efficient solution I'm still interested.
You could use
mpl::zip_view< mpl::vector2< mpl::range_c<0, mpl::size<Descriptors>::value> , Descriptors
as the sequence in your for_each; then each element would contain a compile-time index and a descriptor.
HTH,
Hi everybody, I would like to implement C++ reflection for a product I'm building. The C++ reflection is meant for serializing an object in XML, database, etc. Any recommendation of libraries out there that would help me with this reflection effort? Thanks -delfin
On Wednesday 04 August 2004 2:55 pm, Delfin Rojas wrote:
Hi everybody,
I would like to implement C++ reflection for a product I'm building. The C++ reflection is meant for serializing an object in XML, database, etc. Any recommendation of libraries out there that would help me with this reflection effort?
The next release of Boost will include the serialization library. You might look into that before embarking on your own reflection/serialization library... Doug
On Wednesday 04 August 2004 2:55 pm, Delfin Rojas wrote:
Hi everybody,
I would like to implement C++ reflection for a product I'm building. The C++ reflection is meant for serializing an object in XML, database, etc. Any recommendation of libraries out there that would help me with
"Doug Gregor"
reflection effort?
The next release of Boost will include the serialization library. You might look into that before embarking on your own reflection/serialization library...
Here's a link http://www.rrsd.com/boost/index.htm Jonathan
Istvan Buki writes:
I modified my sample code to take advantage of your suggestion to calculate the index at compile time. It works perfectly well and the code generated is faster than my previous version but I still have questions:
1) I'm not sure if this is the right place to ask, if not somebody will certainly be able to point me into the right direction. In the assembly code generated (file attached to this mail), there are two 'call' instructions that seem useless to me. Why not inline the single 'movl' instruction executed as the result of the call? I'm using g++ 3.3.3 with O2 optimization flag and it is probably a very compiler-specific question but perhaps I'm missing something obvious here.
2) By now you probably guessed that my goal is to produce code for embedded use. In this environment standard libraries would not be available. Could you give me some idea how hard it would be to modify the mpl library not to rely on any standard include and lib?
Should be trivial -- the library has very little dependencies on the standard headers. In fact, 'std::size_t' and LONG_MAX are likely to be the only ones. You'd need to replace the default Boost config headers with your own, though, because those do depend on the presence of various std headers. Please see http://www.boost.org/libs/config/config.htm#advanced_config for the instructions on how to do that. HTH, -- Aleksey Gurtovoy MetaCommunications Engineering
On Friday 06 August 2004 13:06, Aleksey Gurtovoy wrote:
Istvan Buki writes:
I modified my sample code to take advantage of your suggestion to calculate the index at compile time. It works perfectly well and the code generated is faster than my previous version but I still have questions:
1) I'm not sure if this is the right place to ask, if not somebody will certainly be able to point me into the right direction. In the assembly code generated (file attached to this mail), there are two 'call' instructions that seem useless to me. Why not inline the single 'movl' instruction executed as the result of the call? I'm using g++ 3.3.3 with O2 optimization flag and it is probably a very compiler-specific question but perhaps I'm missing something obvious here.
2) By now you probably guessed that my goal is to produce code for embedded use. In this environment standard libraries would not be available. Could you give me some idea how hard it would be to modify the mpl library not to rely on any standard include and lib?
Should be trivial -- the library has very little dependencies on the standard headers. In fact, 'std::size_t' and LONG_MAX are likely to be the only ones. You'd need to replace the default Boost config headers with your own, though, because those do depend on the presence of various std headers. Please see http://www.boost.org/libs/config/config.htm#advanced_config for the instructions on how to do that.
Indeed it was easy to do. I first created my own setup as described on the web site, starting from existing config files and then removing a couple of unknown header files in my environment. After that, the only remaining problem was the type_traits library that include the <cstddef> header in several places to have access to the definition of std::size_t. I simply created my own version of the cstddef header with the appropriate definition for std::size_t and now everything compiles. Thanks for your help, Istvan
participants (6)
-
Aleksey Gurtovoy
-
David Abrahams
-
Delfin Rojas
-
Doug Gregor
-
Istvan Buki
-
Jonathan Turkanis