|
Boost : |
Subject: Re: [boost] Abstract STL Container Adaptors
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2013-03-18 14:05:11
AMDG
On 03/18/2013 10:07 AM, Andy Jost wrote:
> From: Boost [mailto:boost-bounces_at_[hidden]] On Behalf Of Steven Watanabe
>> On 03/18/2013 08:30 AM, Andy Jost wrote:
>>>
>>> Maybe looking at some code would help clarify the answers to these questions. I have about 300 lines partially implementing an adaptor for std::set using Boost.TypeErasure, plus a list of questions and problems I encountered. Is that too large to put into an email for this list? If so, where can I drop it?
>>>
>
>> That shouldn't be too large.
>
> Ok, code is at the end; questions first. I realize many of these questions may be answered in the documentation.
>
> Linux 2.6.9-89.ELlargesmp x86_64
> g++ (GCC) 4.5.2
>
> 1) Certain functions require a downcast, of sorts. The overload of std::set<T>::insert taking an iterator as hint is an example. Not just any iterator, but one with exactly the right type is needed. Maybe this is what type_erasure::is_same is for, but I haven't looked into it yet.
>
This would fall under:
http://boost-sandbox.sourceforge.net/doc/html/boost_typeerasure/multi.html
>
> 2) I start getting errors when the mpl::vector of requirements exceeds 20 elements: "error: wrong number of template arguments (21, should be 20)."
>
> As a blind guess, I tried including boost/mpl/vector/vector30.hpp but it doesn't help. I know there's a good chance the answer is in the MPL docs somewhere, but I haven't had a chance to go deeper.
>
You need to use the numbered form for >20 elements.
i.e. mpl::vector21<...>
>
> 3) I could not implement swap. If item 1 can be resolved, then this could work in the same way. Still, it seems that two any<> objects of the same type should be swappable (though, it is not obvious how that would be expressed). I couldn't find a way to do it.
>
I haven't implemented swap. It would need to look like this:
template<class T>
struct swappable {
static void appy(T& lhs, T& rhs)
{ using std::swap; swap(lhs, rhs); }
};
namespace boost { namespace type_erasure {
// a better match than std::swap
template<class Concept, class T>
void swap(any<Concept, T>& lhs, any<Concept, T>& rhs)
{
call(swappable<typename boost::remove_reference<T>::type>(),
lhs, rhs);
}
template<class T1, class T2>
void swap(any<Concept, T1>& lhs, any<Concept, T2>& rhs)
{
call(swappable<typename boost::remove_reference<T1>::type>(),
lhs, rhs);
}
}}
(BOOST_TYPE_ERASURE_FREE doesn't work because
boost::type_erasure::swap needs to be a better
match than std::swap and boost::swap.)
>
> 4) When members are overloaded based on a constant this, I could only use the const-qualified version. So, I can add a requirement for set<T>::clear, but for set<T>::begin, the return value must be specified as const_iterator.
>
That's odd. It works for me with msvc-11.
I just committed a test case in r83490.
>
> 5) BOOST_TYPE_ERASURE_MEMBER cannot be used in a SEQ_FOR_EACH loop, because it uses SEQ_FOR_EACH internally. It would be handy to have a way to declare several members when the namespace path and prefix (e.g., has_) doesn't change, either by passing the z parameter or using another macro.
>
Sorry. BOOST_PP_SEQ_FOR_EACH is not re-entrant and
I really don't want to try to work around it.
>
> 6) I could never get the bidirectional_iterator concept from TypeErasure working. I didn't find an example.
It should be:
bidirectional_iterator<_iter, T&>,
same_type<bidirectional_iterator<_iter, const T&>::value_type, T>
I think I can get rid of the need to use same_type,
since it doesn't provide any extra information.
> I ended up writing out the requirements myself. Also, that required the use of relaxed and I didn't understand why.
>
It's because of the default constructor.
any<iterator_requirements> x; // creates an empty any, *not* an any
containing a default constructed iterator. Enabled by relaxed.
In Christ,
Steven Watanabe
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk