$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Eric Niebler (eric_at_[hidden])
Date: 2005-12-05 18:53:03
MB wrote:
> 
> Errata:
> 
>    But I think about the case that my ranges which are customized as 'cheap_copy'
>    becomes base classes of anyone else.
> 
>    replaces:
> 
>      >But I think about the case that my ranges which are customized as 'cheap_copy'
>      >are derived from anyone else.
> 
> English is as difficult as C++ :-)
> 
>>>Now that 'has_cheap_copy' becomes one of the requirements of Range-concepts, doesn't it?
>>
>>No. Boost.Range defines the range concept, and FOREACH works correctly 
>>with any type that satisfies that concept. has_cheap_copy is nothing 
>>more than an optimization hint to the BOOST_FOREACH macro. It is not 
>>required and it doesn't change the meaning of anything.
> 
> 
> But the hint expands to the derived classes and
> the derived classes "must" customize 'has_cheap_copy'.
I agree that's not good. I've reimplemented the has_cheap_copy 
customization point again. See below.
> 
>>>In general, do we have the safe way of telling whether or not a type
>>>is cheap to copy without metafunctions?
>>
>>No.
> 
> 
> Is it portability-issue the reason why you avoid metafunctions?
You mean, why isn't there a has_cheap_copy<T> trait? I had originally 
wanted the cheap_copy optimization to automatically apply to derived 
types, which is the reason for the particular form of the customization 
point. I no longer think that's a good idea, so I can now add a 
has_cheap_copy<> trait, however ...
... on compilers without partial template specialization, there isn't a 
good way of saying that for all types T, boost::iterator_range<T> is 
cheap to copy. So the free function template is still the way to go on 
those compilers.
Here is the new-and-improved(-and-please-god-let-this-be-the-last) way 
to optimize FOREACH for cheap-to-copy types:
- For a user-defined range type Foo that is cheap to copy,
   you should specialize has_cheap_copy<> in the boost::foreach
   namespace, as:
     namespace boost { namespace foreach {
       template<>
       struct has_cheap_copy<Foo> : mpl::true_ {};
     }}
- For maximum portability, you could achieve the same effect
   by overloaded boost_foreach_has_cheap_copy() at global scope
   like this:
     inline boost::mpl::true_ *
     boost_foreach_has_cheap_copy(Foo *&, boost::foreach::tag)
     { return 0; }
(The slightly strange Foo *& type prevents this overload from being 
selected for types derived from Foo.)
By default FOREACH defines overloads to recognize std::pair<T,T>, 
iterator_range<T> and sub_range<T> as cheap-to-copy, but NOT types 
derived from them.
I hope this is satisfactory.
-- Eric Niebler Boost Consulting www.boost-consulting.com