From: stephan b. <st...@wa...> - 2003-10-05 22:14:44
|
De/serializing arbitrary containers of Serializable pointers is old-hat, = but=20 here's something new: last night i found a way to de/ser arbitrary STL=20 containers of non-pointer, non-Serializable child objects. Thus serializing your vector of ints is now: node.serializeList( "mynode", myvec ); node.deserializeList( "mynode", myvec ); It's just as easy for std::map instantiations: typedef std::map<int,string> MyMap; MyMap map; map[0] =3D "foo"; map[1] =3D "bar"; node.serializeMap( "mymap", map ); and: node.deserializeMap( "mymap", map ); This works by using std::map<>'s key_type and mapped_type typedefs, and t= hen=20 passing those typedefs to t/from_string() functions which actually do the= =20 data conversion to/from the appropriate types (i.e., same as how Property= List=20 does it). There is major caveat with maps: the keys must be suitable as property na= mes.=20 That is, numbers won't work for some input parsers because they don't tre= at=20 numbers as valid key names. The data ends up looking something like: int_to_str_map class=3Ds11n::S11nNode { 0 eek! 2 ggggaaaawwwwwwkkk! 4 yet another string } dbl_to_str_map class=3Ds11n::S11nNode { 1.000000 eek! 3.000000 ggggaaaawwwwwwkkk! 5.000000 yet another string } (i don't know if fun's txt parser handles numeric keys? i had to explicit= ely=20 add that support to my parsers.) They were relatively simple to implement. Here's the whole code for the m= ap=20 variants (list-style code is very similar): template <typename ContainerType> unsigned long serializeMap( const std::string & nodename, const Container= Type=20 & map ) { unsigned long ret =3D 0; typedef typename ContainerType::const_iterator CIT; CIT it =3D map.begin(); CIT et =3D map.end(); if( it =3D=3D et ) return ret; S11nNode * node =3D new S11nNode(nodename); for( ; it !=3D et; ++it ) { node->set( elib::to_string( (*it).first ), (*it).second )= ; ++ret; } if( 0 =3D=3D ret ) delete( node ); else this->children().push_back( node ); return ret; } template <typename ContainerType> unsigned long deserializeMap( const std::string & nodename, ContainerType= &=20 map ) const { unsigned long ret =3D 0; const S11nNode * node =3D this->child( nodename ); if( ! node ) return ret; typedef typename ContainerType::value_type PairT; typedef typename ContainerType::key_type KT; typedef typename ContainerType::mapped_type VT; // is called data= _type=20 in the SGI docs! S11nNode::const_iterator spit =3D node->begin(); S11nNode::const_iterator spet =3D node->end(); VT defaultval =3D VT(); KT defaultkey =3D KT(); for( ; spit !=3D spet; ++spit ) { KT key =3D elib::from_string( (*spit).first, defaultkey )= ; VT val =3D elib::from_string( (*spit).second, defaultval = ); map.insert( PairT( key, val ) ); ++ret; } return ret; } --=20 ----- st...@wa... http://qub.sourceforge.net http://libfunutil.sourceforge.net =20 http://toc.sourceforge.net http://countermoves.sourceforge.net http://stephan.rootonfire.org |