Boost logo

Boost :

From: Jan Langer (jan_at_[hidden])
Date: 2003-02-03 12:34:18


Vladimir Prus wrote:
>> i needed that (or maybe something similar) for the filesystem
>> attributes in the sandbox. i tried to make it compatible to the
>> property map concept. the output can be used as follows (taken from
>> boost-sandbox/libs/filesystem/test/type_pm_test.cpp)
>
> AFAIKT, this is quite close to what I wanted/had. And this is indeed
> different
> from associative_list-based solution, although subtly. Here, you can store
> arbitrary number of types and those types are looked up at runtime. With
> associative_list you'd store a number of pointers of predefined types
> and lookup is done at compile time.

no, you can store an arbitrary number of objects of the same type. and
they are just looked up with the type. that means to implement what you
want there should be a type_property_map <boost::any> where the get/put
functions convert from any to the looked up type. i took the cache class
as it is in the sandbox and modified it. now it should meet your needs
(it still needs the original type_property_map):

         class type_pm
         {
             public:
                 typedef read_write_property_map_tag category;

                 // access on a certain value
                 // at is used because operator[] is not
                 // possible without an object as key
                 template <typename T>
                 T &at ()
                 {
                     any &a = map_.template at <T> ();
                     // no object of this type exists yet
                     // -> construct one
                     if (a.empty ())
                         a = T (*this);

                     // conversion to required type
                     T *v = any_cast <T> (&a);
                     assert (v);
                     return *v;
                 }

             private:
                 typedef detail::type_property_map <any> map_type;
                 map_type map_;
         };

         template <typename T>
         T &get (type_pm &pmap)
         {
             return pmap.template at <T> ();
         }

         template <typename T>
         void put (cache &pmap, T v)
         {
             pmap.template at <T> () = v;
         }

usage:
        type_pm a;

        put <int> (a, 7);
        put <char> (a, 'i');
        put <char> (a, 'b');

        assert (get <int> (a) == 7);
        assert (get <char> (a) == 'b');
        assert (a.template at <int> () == 7);

the a.template at () is really ugly but i found no better solution.

> Which one is best, depends on the problem domain. For example, you could
> allow
> user to define custom filesystem attributes, provided that classes for
> that attributes can be constructed from boost::path. (I see that now
> attributes are constructed with cache& as parameter, but that allows for
> user-defined attributes as well). Consequently, you need dynamic
> behaviour. Looks like BGL
> does not need it, and can use associative_list.
>
>> boost::filesystem::detail::
>> type_property_map <char> pm;
>>
>> put <int> (pm, 'i');
>
> Well, this looks pretty confusing, I'd even say dangerous. If the
> property map
> holds chars, then putting int there is questionable.

no, the type stored in the map is char. and int is the lookup key. i
dont know if bgl needs it. i just thougth that it migth be something
which also could help in another situation than only filesystem.
jan

-- 
jan langer ... jan_at_[hidden]
"pi ist genau drei"

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk