On Tue, 6 Jan 2004, Lars Gullik Bjønnes wrote:

> Depends on how verbose you want to be... 
> 
>    indirect_iterator<LayoutList::iterator> it =
>            find_if(make_indirect_iterator(layoutlist_.begin()),
>                    make_indirect_iterator(layoutlist_.end()),
>                    LayoutNamesEqual(name));
> 
>    LayoutList::iterator rit = it.base();
>    return rit != layoutlist_.end();
> 
> But does this really make things simpler to read?

Yes and no... (no because of the long_and_complicated_type_definitions ;-)

Although this looks pretty good to me as a compromise:

    indirect_iterator<LayoutList::iterator>
            it = find_if(make_indirect_iterator(layoutlist_.begin()),
                         make_indirect_iterator(layoutlist_.end()),  
                         LayoutNamesEqual(name));

    return it.base() != layoutlist_.end();

Where I think the 'it =' looks better in front of 'find_if(...').

Btw, why use 'layoutlist_.begin()' rather than 'begin()' (I just had a 
look at lyxtextclass.h and saw that
         /// paragraph styles begin iterator.
        const_iterator begin() const { return layoutlist_.begin(); }
        /// paragraph styles end iterator
        const_iterator end() const { return layoutlist_.end(); }

> I'd rather write LayoutNamesEqual for LyXLayout than LyXLayout_ptr,
> so:
> 
>         return count_if(make_indirect_iterator(layoutlist_.begin()),
>                         make_indirect_iterator(layoutlist_.end()),
>                         LayoutNamesEqual(name));

I agree that writing LayoutNamesEqual() for the 'object' instead of a ptr 
to it is better. (I didn't think of that distinction). 
Where does 'make_indirect_iterator()' come from -- is it standard?
(I couldn't find it mentioned in C++ Annotations)

Earlier you wrote:
> My main reason was to avoid creating LayoutNamesEqual special cases
> for LyXLayout_ptr (a shared_ptr) and rather have it work for
> LyXLayout directly. That is what the indirect_iterator is about; it
> adds an additional derefernce before sending the object to the
> predicate.

Because elements of layoutlist_ are pointers you use
         ... it = make_indirect_iterator(...); 
where the 'it' operates on target of the pointer rather than the pointer.

Unfortunately I find the name 'make_indirect_iterator' a bit confusing, 
it somehow makes me think it's the other way around, i.e. that layoutlist_
contains the objects etc. Oh well.

> | which should work as long as the n:o layouts isn't _huge_.
> 
> count_if could be used... but it will always be O(n) whereas find_if
> will be O(n/2) on average when the layout exists and O(n) if not.
> 
> But I am not sure if we should care about efficiency here.
> Opinions on this issue?

How often would this function be called... but I guess the "proper" thing 
would be to create a generic algorithm called something like 'has_if',
'or_if', 'map_or' or 'map_predicate_or' that implements
        predicate(element1) || predicate(element2) || ...
with "short-circuited" logic. I don't suppose there already is a function 
like this around?

/Christian

-- 
Christian Ridderström                           http://www.md.kth.se/~chr






Reply via email to