$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Dan Posluns (dan_at_[hidden])
Date: 2007-09-07 21:22:20
I've been trying to use MPL to create a system on an embedded platform 
(where memory is at a premium and dynamic allocations are expensive) 
that allows for multiple components or properties to be combined into a 
single object at both compile and run-time.
The basic idea is, say I have the following properties for a 3D model 
(each its own independent class; there are more than the examples I list 
here):
ModelBase
Configuration
JointAnimation
TextureAnimation
LightingConfig
I know that a box doesn't need JointAnimation, so when I instantiate a 
Model for it I'd like it to not have that "property".
(I could easily accomplish all of this using a std::map and a dynamic 
allocation for each property, but again, it's prohibitive on the 
platform and I'd rather use metaprogramming if I can.)
So what I'd like to do, in theory, is something like:
// Declare a generic class for a property-based object that templates 
off of the set of properties it can contain
template<class PropertiesSet>
class ObjectWithProperties
{
public:
    // Create an instance of ObjectWithProperties, using some subset of 
PropertiesSet
    template<class PropertiesSubset>
    static ObjectWithProperties *create();
    // Attempt to retrieve a Property, return null on failure
    template<class PropertyType>
    PropertyType *getProperty();
private:
    SomeStaticListManager< size<PropertiesSet>::value > 
which_properties_are_used;
    void *data_buffer_for_properties;
};
// Define the set of properties that a model can consist of
typedef set<ModelBase, Configuration, JointAnimation, TextureAnimation, 
LightingConfig> ModelPropertiesSet;
// Define a Model as an object with those properties
typedef ObjectWithProperties<ModelPropertiesSet> Model;
// Instantiate a model with only certain properties:
Model   *m = Model::Create< set<ModelBase, Configuration> >();    // A 
Model that only has two properties
The Create() method would iterate over the subset, tally up the sizeof() 
for each class, and then perform a single allocation for 
data_buffer_for_properties and proceed to use placement new to 
instantiate each class in the subset. (The destructor would then clean 
up all of that ugliness.)
The which_properties_are_used member would be an efficient list manager 
that can be used to lookup the existence of properties, indexing the 
types in the set using the order<> operator.
Unfortunately, I haven't been able to get very far with set<>. I tried 
the following:
typedef fold<
        PropertiesSubset,
        int_<0>,
        plus< _1, sizeof_<_2> >
    >::type TotalSize;
cout << TotalSize::value;
... and it gives me nothing like what I'm looking for. The documentation 
hasn't been much help, and I haven't even begun to attempt iterating an 
actual function over the set (would that be for_each<>?).
Any help or ideas to alternative approaches would be greatly appreciated!
Thanks,
Dan.
-- Dan Posluns, B. Eng. & Scty. (Software Engineering and Society) dan_at_[hidden] - ICQ: 35758902 http://www.danposluns.com "The great thing about being the only species on the planet that makes a distinction between right and wrong is that we get to make the rules up for ourselves as we go." - Douglas Adams, Last Chance to See