Home > Coding > Working with traits…

Working with traits…

URGH!

I’m trying to write something along the lines of:


template<typename _ItrType>
static size_t countThings(_ItrType begin, _ItrType end)
{
  size_t numThings = 0 ;
  for ( _ItrType it = begin ; it != end ; ++it )
  {
    Entity& entity = getEntityFromIterator(it) ;
    numThings += entity.numThings ;
  }
}

// Handle associative iterators.
template<typename _KeyType>
Entity& getEntityFromIterator(std::pair<_KeyType, Entity&>& it)
{
  return it.second ;
}

template<typename _KeyType>
Entity& getEntityFromIterator(std::pair<_KeyType, Entity*>& it)
{
  return *(it.second) ;
}

template<typename _KeyType>
Entity& getEntityFromIterator(std::pair<_KeyType, Entity>& it)
{
  return it.second ;
}

// Handle sequence iterators.
template<typename _ItrType>
Entity& getEntityFromIterator(_ItrType& it)
{
  return *it ;
}

I.e. something that will allow me to write a function that will take an iterator range and worry about whether the iterators are sequence or container for me at compile time.

But it always falls thru to my last case. The error from GCC indicates that I need to specifically look  std::_RB_tree_iterator<std::pair<_KeyType, Entity>> etc, but I'd rather not. I'm wanting to do something to peel back until we get to an Entity, e.g.

template<typename _Outer, typename _Inner>get(_Outer<_Inner>& container) { return *container ; }
template<typename _Key, typename _Value> get(_Key, _Value entity) { return get(entity) ; }
get(Entity& entity) { return entity ; }
get(Entity* entity) { Return *entity ; }

Cannot seem to find a way to get this to work, and I'm starting to think I probably need to do some traits jiggery-pokery. Grr.

Categories: Coding Tags: ,
  1. Lutorm
    September 27, 2011 at 4:21 pm

    I don’t see how this could work. map::iterator is not a pair, it *dereferences* to a pair.

    Wouldn’t it work to instead of getEntityFromIterator(it) use getEntity(*it), which would be defined just as in your example except the last case would just do “getEntity(const Entity& e) { return e;}” plus a similar definition taking an Entity*.

    It seems that getEntity… doesn’t need to iterate on the iterator, in which case it should work just as well to send it a dereferenced iterator which you know will be either an Entity, Entity* or a pair.

  2. October 2, 2011 at 3:54 pm

    I just realized … I’ve actually done this before, and got it working.

        SINT32 send(SINT32 teulIndex) const ;
        
    public:
        // Handle sequence container of SINT32 teulIndexes
        template<typename _Iterator>
        SINT32 send(const _Iterator& start, const _Iterator& end) const
        {
            if ( start == end ) return 0 ;
            if ( !_checkData() ) return -EINVAL ;
            UINT32 sent = 0 ;
            _Iterator next = start ;
            do
            {
                _Iterator cur = next ;
                ++next ;
                if ( send(*cur) >= 0 )
                    sent++ ;
            }
            while ( next != end ) ;
            return sent ;
        }
    
        // Handle sequence container of SINT32 teulIndexes
        template<typename _Iterator, typename _Filter>
        SINT32 send(const _Iterator& start, const _Iterator& end, const _Filter& filter) const
        {  
            if ( start == end ) return 0 ;
            if ( !_checkData() ) return -EINVAL ;
            UINT32 sent = 0 ;
            _Iterator next = start ;
            do
            {  
                _Iterator cur = next ;
                ++next ;
                if ( filter(*cur) && send(*cur) )
                    sent++ ;
            }
            while ( next != end ) ;
            return sent ;
        }
    
        template<typename _Key, typename _Data> SINT32 send(std::pair<_Key,_Data>& t) const { return send(t.second) ; }
        template<typename _Type> SINT32 send(const _Type* t) const { return send(t->teulIndex()) ; }
        template<typename _Type> SINT32 send(_Type* t) const { return send(t->teulIndex()) ; }
        template<typename _Type> SINT32 send(const _Type& t) const { return send(t.teulIndex()) ; }
    
    
  3. October 2, 2011 at 3:55 pm

    … which once again reminds me how much working with C++ templates is like functional programming, because order of declaration is so important…

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 216 other followers

%d bloggers like this: