std::map replacement

Discussion in 'C++' started by Christopher Benson-Manica, May 12, 2004.

  1. If you liked the functionality of std::map, but found that you
    couldn't trust your implementation to handle nonstandard data
    structures, how would you code a wrapper? I've produced the
    following:

    #include <map>

    template < class keytype, class recordtype >
    class pseudomap
    {
    private:
    map< keytype, unsigned int > maptable;
    CustomList<recordtype> recordlist; // custom array-like class
    // with methods including
    // those used below

    public:
    void clear() {maptable.clear();recordlist.Clear();}

    recordtype& operator[] ( const keytype& key )
    {
    if( maptable.count(key) ) {
    return( *recordlist[maptable[key]] );
    }
    recordlist.Add( new recordtype() );
    maptable[key]=recordlist.Count-1;
    return( *recordlist[maptable[key]] );
    }
    };

    I get the feeling that there is a lot to criticize about the code
    above (although it seems to work just fine) - so I'm listening :)
    Needless to say not all map functionality is included - but it's good
    enough for my current needs...

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 12, 2004
    #1
    1. Advertising

  2. Christopher Benson-Manica

    Andre Kostur Guest

    Christopher Benson-Manica <> wrote in
    news:c7u0tl$3dt$:

    > If you liked the functionality of std::map, but found that you
    > couldn't trust your implementation to handle nonstandard data
    > structures, how would you code a wrapper? I've produced the
    > following:


    What do you call "nonstandard data structures"?

    > #include <map>
    >
    > template < class keytype, class recordtype >
    > class pseudomap
    > {
    > private:
    > map< keytype, unsigned int > maptable;
    > CustomList<recordtype> recordlist; // custom array-like class
    > // with methods including
    > // those used below
    >
    > public:
    > void clear() {maptable.clear();recordlist.Clear();}
    >
    > recordtype& operator[] ( const keytype& key )
    > {
    > if( maptable.count(key) ) {
    > return( *recordlist[maptable[key]] );
    > }
    > recordlist.Add( new recordtype() );
    > maptable[key]=recordlist.Count-1;
    > return( *recordlist[maptable[key]] );
    > }
    > };
    >
    > I get the feeling that there is a lot to criticize about the code
    > above (although it seems to work just fine) - so I'm listening :)
    > Needless to say not all map functionality is included - but it's good
    > enough for my current needs...


    How can we tell? You haven't stated what exactly you're trying to
    accomplish!
     
    Andre Kostur, May 13, 2004
    #2
    1. Advertising

  3. Christopher Benson-Manica <> wrote in message news:<c7u0tl$3dt$>...
    > If you liked the functionality of std::map, but found that you
    > couldn't trust your implementation to handle nonstandard data
    > structures, how would you code a wrapper?


    By wrapping the non-standard data or implementing a proper
    std::less<non_standard_data>.

    Regards,
    Michiel Salters
     
    Michiel Salters, May 13, 2004
    #3
  4. Michiel Salters <> spoke thus:

    > By wrapping the non-standard data or implementing a proper
    > std::less<non_standard_data>.


    Well, the key was an unsigned int (the user-defined data was the
    value), so I don't think the comparison function was the problem.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #4
  5. Andre Kostur <> spoke thus:

    > How can we tell? You haven't stated what exactly you're trying to
    > accomplish!


    I thought I did - to create a data structure that acts like a map but
    uses a map with only simple data types as the values. As I stated,
    when using a class I defined as the second map template parameter,
    things broke, and as far as I can tell it isn't my fault...

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #5
  6. Christopher Benson-Manica wrote:
    >
    > Andre Kostur <> spoke thus:
    >
    > > How can we tell? You haven't stated what exactly you're trying to
    > > accomplish!

    >
    > I thought I did - to create a data structure that acts like a map but
    > uses a map with only simple data types as the values. As I stated,
    > when using a class I defined as the second map template parameter,
    > things broke, and as far as I can tell it isn't my fault...


    Show your class.
    In almost all cases it *is* your fault.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, May 13, 2004
    #6
  7. Karl Heinz Buchegger <> spoke thus:

    > Show your class.
    > In almost all cases it *is* your fault.


    Verbatim, with some names changed:

    struct
    MyClass {
    private:
    CustomClassA e;

    public:
    bool Valid;

    _TDate Start;
    _TDate End;
    uint blockMTD;
    uint blockYTD;
    uint creditMTD;

    bool HasNextPeriod;
    _TDate nbStart;
    _TDate nbEnd;
    uint nbBlock;
    uint nbCredit;

    CustomClassB Exceptions; // list of CustomClassA's
    void AddException( uint id, uint date, uint time ) {Exceptions.AddException(id,date,time);}
    void AddException( const char *str ) {e.FromString(str);Exceptions.Add(e);}

    EmployeeEvalInfo() {Valid=false;HasNextPeriod=false;Start=0;End=0;blockMTD=0;blockYTD=0;creditMTD=0;nbStart=0;nbEnd=0;nbBlock=0;nbCredit=0;}
    };

    Unless the implementations of CustomClassA and CustomClassB matter, I
    don't see what the problem can be...

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #7
  8. Christopher Benson-Manica

    Derek Guest

    Christopher Benson-Manica wrote:

    > If you liked the functionality of std::map, but found
    > that you couldn't trust your implementation to handle
    > nonstandard data structures, how would you code a
    > wrapper?


    I'm not clear on what you mean by "nonstandard data
    structures" and why you can't just insert your objects
    into a std::map directly.

    Are you getting compiler errors? Are you seeing
    unexpected results at runtime?
     
    Derek, May 13, 2004
    #8
  9. Derek <> spoke thus:

    > Are you getting compiler errors? Are you seeing
    > unexpected results at runtime?


    Unexpected results at runtime, and the debugger points at the std::map
    implementation...

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #9
  10. Christopher Benson-Manica

    Jeff Flinn Guest

    "Christopher Benson-Manica" <> wrote in message
    news:c7vpt9$jhf$...
    > Karl Heinz Buchegger <> spoke thus:
    >
    > > Show your class.
    > > In almost all cases it *is* your fault.

    >
    > Verbatim, with some names changed:
    >
    > struct
    > MyClass {
    > private:
    > CustomClassA e;
    >
    > public:
    > bool Valid;
    >
    > _TDate Start;
    > _TDate End;
    > uint blockMTD;
    > uint blockYTD;
    > uint creditMTD;
    >
    > bool HasNextPeriod;
    > _TDate nbStart;
    > _TDate nbEnd;
    > uint nbBlock;
    > uint nbCredit;
    >
    > CustomClassB Exceptions; // list of CustomClassA's
    > void AddException( uint id, uint date, uint time )

    {Exceptions.AddException(id,date,time);}
    > void AddException( const char *str )

    {e.FromString(str);Exceptions.Add(e);}
    >
    > EmployeeEvalInfo()

    {Valid=false;HasNextPeriod=false;Start=0;End=0;blockMTD=0;blockYTD=0;creditM
    TD=0;nbStart=0;nbEnd=0;nbBlock=0;nbCredit=0;}
    > };
    >
    > Unless the implementations of CustomClassA and CustomClassB matter, I
    > don't see what the problem can be...


    I'm sure they do matter! All of your classes used here must be default
    constructible, and copyable/assignable. If that is not possible define your
    map as std::map< key, boost::shard_ptr<Myclass> >

    Jeff F
     
    Jeff Flinn, May 13, 2004
    #10
  11. Jeff Flinn <> spoke thus:

    > I'm sure they do matter! All of your classes used here must be default
    > constructible, and copyable/assignable. If that is not possible define your
    > map as std::map< key, boost::shard_ptr<Myclass> >


    Well, I can't use boost, and I can't change how these classes are
    implemented, so I guess I'll stick with what I posted originally.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #11
  12. Christopher Benson-Manica

    Derek Guest

    Christopher Benson-Manica wrote:
    > > Are you getting compiler errors? Are you seeing
    > > unexpected results at runtime?

    >
    > Unexpected results at runtime, and the debugger points at
    > the std::map implementation...


    Unless you are using an ancient or highly broken standard
    library, I doubt it's the std::map implementation.

    More likely that your "nonstandard" value class doesn't
    implement correct copy semantics or contains some other bug.
     
    Derek, May 13, 2004
    #12
  13. Christopher Benson-Manica

    Derek Guest

    Christopher Benson-Manica wrote:
    > > I'm sure they do matter! All of your classes
    > > used here must be default constructible, and
    > > copyable/assignable. If that is not possible define
    > > your map as std::map< key, boost::shard_ptr<Myclass> >

    >
    > Well, I can't use boost, and I can't change how these
    > classes are implemented, so I guess I'll stick with what
    > I posted originally.


    Why can't you use boost? Another possibility is to
    use raw pointers and manage lifetime yourself, eg,
    std::map<key, MyClass*>.

    If the problem is that if your classes don't use correct
    copy/assignment semantics, your wrapper may be very
    fragile. It may work now, but it may fail completely on
    another platform or stop working when you make what seems
    like an unrelated change. Best to get to the root cause
    of the problem.
     
    Derek, May 13, 2004
    #13
  14. Derek <> spoke thus:

    > Why can't you use boost?


    It isn't my decision to make.

    > Another possibility is to
    > use raw pointers and manage lifetime yourself, eg,
    > std::map<key, MyClass*>.


    I suppose, but it'd be a hassle.

    > If the problem is that if your classes don't use correct
    > copy/assignment semantics, your wrapper may be very
    > fragile.


    Well, if it's fragile, it's because the custom classes are fragile; I
    think map< int, int > is pretty stable.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #14
  15. Derek <> spoke thus:

    > Unless you are using an ancient or highly broken standard
    > library, I doubt it's the std::map implementation.


    It's Borland 4, and I've found several instances where it's either
    flat broken or breaks when our custom libraries are linked in.

    > More likely that your "nonstandard" value class doesn't
    > implement correct copy semantics or contains some other bug.


    Possibly :)

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #15
  16. Christopher Benson-Manica

    Jeff Flinn Guest

    "Christopher Benson-Manica" <> wrote in message
    news:c7vvqj$leo$...
    > Derek <> spoke thus:
    >
    > > Why can't you use boost?

    >
    > It isn't my decision to make.


    Just curious as to the reason boost isn't allowed?

    >
    > > Another possibility is to
    > > use raw pointers and manage lifetime yourself, eg,
    > > std::map<key, MyClass*>.

    >
    > I suppose, but it'd be a hassle.


    You'd be better off writing a wrapper for MyClass with appropriate
    default/copy constructors than re-implementing a custom map.

    Your already dealing with pointers in your pseudomap class, are you not?
    It's difficult to comment on your code since much of the implementation
    appears to be in CustomList<recordtype> which you didn't supply. But, I
    don't understand why you even have the CustomList? You could:


    Untested code follows:

    template < class keytype, class recordtype >
    class SeverelyLimitedMap
    {
    private:
    typedef std::map< keytype, recordtype* > tPtrs;

    tPtr mPtrs;

    static void DeletePtr( typename tPtrs::value_type& aPair )
    {
    delete aPair.second;
    }

    public:
    void clear()
    {
    std::for_each( mPtrs.begin(), mPtrs.end(), DeletePtr );

    mPtrs.clear();
    }

    recordtype& operator[] ( const keytype& key )
    {
    tPtrs::iterator lItr = mPtrs.find( key );

    if( lItr != mPtrs.end() )
    {
    return *lItr;
    }
    else
    {
    return *mPtrs.insert( tPtrs::value_type( key, new
    recordtype ) ).first;
    }
    }
    };


    Jeff F
     
    Jeff Flinn, May 13, 2004
    #16
  17. Christopher Benson-Manica

    Default User Guest

    Derek wrote:

    > Why can't you use boost? Another possibility is to
    > use raw pointers and manage lifetime yourself, eg,
    > std::map<key, MyClass*>.



    I've ranted about this before. Boost is not a part of standard C++. It
    is a third-party library at this time. For those of us that work in a
    controlled environment (you know like that make your planes fly and
    stuff?) we can't willy-nilly throw in code that's not been approved.

    It's fine for writing your non-security conscious programs, but for
    others you'd have to get the appropriate people to review and pass on
    the Boost library.



    Brian Rodenborn
     
    Default User, May 13, 2004
    #17
  18. Jeff Flinn <> spoke thus:

    > Just curious as to the reason boost isn't allowed?


    I'm still trying to convince my boss that the STL is a Good Thing
    (tm), with only limited success. He certainly wouldn't trust boost :)

    > You'd be better off writing a wrapper for MyClass with appropriate
    > default/copy constructors than re-implementing a custom map.


    It sounds like a good exercise. I'd try that, except that I don't
    know enough about MyClass' implementation to do it... (among other
    things, I'm not positive that it manages its memory with malloc,
    although I think it does).

    > Your already dealing with pointers in your pseudomap class, are you not?
    > It's difficult to comment on your code since much of the implementation
    > appears to be in CustomList<recordtype> which you didn't supply. But, I
    > don't understand why you even have the CustomList? You could:


    Well, using the CustomList is a nod to existing code :)

    > Untested code follows:


    I've got to do some actual work here, but I'll take a look at that
    sometime - thanks.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, May 13, 2004
    #18
  19. Christopher Benson-Manica

    Derek Guest

    > > Why can't you use boost?
    >
    > I've ranted about this before. Boost is not a part
    > of standard C++. It is a third-party library at this
    > time. For those of us that work in a controlled
    > environment (you know like that make your planes fly and
    > stuff?) we can't willy-nilly throw in code that's not
    > been approved.
    >
    > It's fine for writing your non-security conscious
    > programs, but for others you'd have to get the
    > appropriate people to review and pass on the Boost
    > library.


    I share your concerns, but the only Boost component
    mentioned in this thread was boost::shared_ptr. Even
    though my employer does not allow Boost in general, we
    do use shared_ptr because (a) it's safer than the smart
    pointers we wrote in house, (b) it's very portable, and
    (c) it's very likely to be in the next standard.

    Of course if your application is so critical that it "makes
    planes fly and stuff," then Boost may not be appropriate.
    In fact, I'm not sure C++ is entirely appropriate in such
    circumstances, unless used as a limited subset of the full
    language. I'd rather not think what my 747 autopilot will
    do when 'new' throws std::bad_alloc. ;)
     
    Derek, May 13, 2004
    #19
  20. Christopher Benson-Manica

    Pete Becker Guest

    Derek wrote:
    >
    > I'd rather not think what my 747 autopilot will
    > do when 'new' throws std::bad_alloc. ;)


    If you don't trust the author of the software to handle bad_alloc
    correctly why do you trust him to handle a null pointer correctly?

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, May 13, 2004
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthias Hildebrand
    Replies:
    5
    Views:
    8,201
    krogers
    Mar 20, 2012
  2. Peter Jansson
    Replies:
    5
    Views:
    6,441
    Ivan Vecerina
    Mar 17, 2005
  3. Replies:
    1
    Views:
    456
    red floyd
    Dec 21, 2008
  4. Thomas J. Gritzan
    Replies:
    6
    Views:
    1,051
    James Kanze
    Dec 22, 2008
  5. James Kanze
    Replies:
    0
    Views:
    2,068
    James Kanze
    Dec 21, 2008
Loading...

Share This Page