Is there any container for this?
Hello,
I have some resources I need to address by ID (integer) and name (string). I have thought of using stl::hashmaps
but they only allow a key. Is there any other way to do this?. I have think about using two hashmaps but then, it is a bit tricky when removing elements from the hashmaps.
Thanks in advance,
HexDump.
You might be able to use a std::map, and use a std::pair<int, std::string> as the key. I think the comparison operators for the std::pair type should be enough for the map to sort and retrieve based on the key.
You might want to make some typedefs to simplify things though. Iterators and such are gonna be kinda messy, being a std::pair containing a std::pair and a resource.
std::map<std::pair<int, std::string>, t_Resource> Map;
You might want to make some typedefs to simplify things though. Iterators and such are gonna be kinda messy, being a std::pair containing a std::pair and a resource.
If you're ok with using development code, Boost has a multi-index container library in CVS.
Of course, if it's not urgent, you could just wait until they actually release it. [grin]
Of course, if it's not urgent, you could just wait until they actually release it. [grin]
Quote:Original post by HexDump
Hello,
I have some resources I need to address by ID (integer) and name (string). I have thought of using stl::hashmaps
but they only allow a key. Is there any other way to do this?. I have think about using two hashmaps but then, it is a bit tricky when removing elements from the hashmaps.
Thanks in advance,
HexDump.
No need for removals to be tricky...
class CResourceMap
{
std::map< int , CResource * > Map_ID2Resource;
std::map< std::string , CResource * > Map_Name2Resource;;
std::map< CResource * , std::pair< int , std::string > > Map_Resource2IDName;
public:
void Register( int I , const std::string & Name , CResource * Resource )
{
Map_ID2Resource = Resource;<br> Map_Name2Resource[ Name ] = Resource;<br> Map_Resource2IDName[ Resource ] = pair( I , Name );<br> }<br> <span class="cpp-keyword">void</span> Unregister( <span class="cpp-keyword">int</span> I )<br> {<br> CResource * Resource = Map_ID2Resource;<br> std::string Name = Map_Resource2IDName[ Resource ].second;<br> Map_ID2Resource.remove( I );<br> Map_Name2Resource.remove( Name );<br> Map_Resource2IDName.remove( Resource );<br> }<br> <span class="cpp-keyword">void</span> Unregister( <span class="cpp-keyword">const</span> std::string & Name )<br> {<br> CResource * Resource = Map_Name2Resource[ Name ];<br> <span class="cpp-keyword">int</span> I = Map_Resource2IDName[ Resource ].first;<br> Map_ID2Resource.remove( I );<br> Map_Name2Resource.remove( Name );<br> Map_Resource2IDName.remove( Resource );<br> }<br> <span class="cpp-keyword">void</span> Unregister( CResource * Resource )<br> {<br> <span class="cpp-keyword">int</span> I = Map_Resource2IDName[ Resource ].first;<br> std::string Name = Map_Resource2IDName[ Resource ].second;<br> Map_ID2Resource.remove( I );<br> Map_Name2Resource.remove( Name );<br> Map_Resource2IDName.remove( Resource );<br> }<br> CResource * Lookup( <span class="cpp-keyword">const</span> std::string & Name )<br> {<br> <span class="cpp-keyword">return</span> Map_Name2Resource[ Name ];<br> }<br> CResource * Lookup( <span class="cpp-keyword">int</span> I )<br> {<br> <span class="cpp-keyword">return</span> Map_ID2Resource( I );<br> }<br>};<br><br></pre></div><!–ENDSCRIPT–><br><br>I'm curious, however, why you need two indexes. You'd probably want to templatize the above class, and replace the Map_Resource2IDName definition with a pair of iterators instead of the actual lookups.<br><br>edit:-> [ source ]<br><br><!--EDIT--><span class=editedby><!--/EDIT-->[Edited by - MaulingMonkey on August 27, 2004 1:22:21 PM]<!--EDIT--></span><!--/EDIT-->
And since I was bored, the templatized version:
Warning: untested ^_^
edit: typeo
[Edited by - MaulingMonkey on August 27, 2004 2:54:20 PM]
template < typename IndexT1 , typename IndexT2 , typename BaseType > class DualMap{ typedef std::hash_map< IndexT1 , BaseType * > TMap1; typedef std::hash_map< IndexT2 , BaseType * > TMap2; TMap1 Map_T12Resource; TMap2 Map_T22Resource; std::hash_map< BaseType * , std::pair< TMap1::iterator , TMap2::iterator > > Map_Base2Types;public: void Register( const IndexT1 & I1 , const IndexT2 & I2 , const BaseType * Resource ) { TMap1::iterator I1Iterator = Map_T12Resource.insert( I1 ).first; *I1Iterator = Resource; TMap2::iterator I2Iterator = Map_T22Resource.insert( I2 ).second; *I2Iterator = Resource; Map_Base2Types[ Resource ] = pair( I1Iterator , I2Iterator ); } void Unregister( const BaseType * Resource ) { Map_T12Resource.remove( Map_Base2Types[ Resource ].first ); Map_T22Resource.remove( Map_Base2Ttpes[ Resource ].second ); Map_Base2Types.remove( Resource ); } void Unregister( const IndexT1 & Index ) { BaseType * Resource = Map_T12Resource[ Index ]; } void Unregister( const IndexT2 & Index ) { BaseType * Resource = Map_T22Resource[ Index ]; } BaseType * Lookup ( const IndexT1 & Index ) const { return Map_T12Resource[ Index ]; } BaseType * Lookup ( const IndexT2 & Index ) const { return Map_T22Resource[ Index ]; }};
Warning: untested ^_^
edit: typeo
[Edited by - MaulingMonkey on August 27, 2004 2:54:20 PM]
Is the ID pre-determined or can it be arbitrary as long as it's unique? If you can set the ID to anything you want just use the hash of the name string as the ID and then use a container with a single integer key that is the hashed ID.
Well, I need 2 indexes because I coudl want to get/set a resource or something by id or name. No one has had this problem before :?. Perhaps I´m doing something wrong.
HexDUmp
HexDUmp
Oh, ID OR name. Ignore my comments, then. I was totally thinking ID and name together as a key.
Quote:Original post by mattnewport
Is the ID pre-determined or can it be arbitrary as long as it's unique? If you can set the ID to anything you want just use the hash of the name string as the ID and then use a container with a single integer key that is the hashed ID.
But a hash function doesn't guarantee that its result is unique for each key. Otherwise, it wouldn't be a hash function.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement