$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Martin Wartens (martin.wartens_at_[hidden])
Date: 2004-12-02 11:12:17
Hi,
I came up with a solution that seems to work. It is as simple as adding "const" 
to the Value template parameter of the iterator_adapter. Then I can have a non-
const iterator that always returns const when dereferenced. Unfortunately, the 
iterator_adapter class has a public member function "base" that returns the 
underlying iterator. Since I want to prevent public access to the underlying 
operator, I had to tweak iterator_adapter and make this function protected. 
Then I want to give access to the base function only to the container adaptor 
(a map adaptor in my example). Providing the friend access in a generic way is 
a little bit awkward, as it has to be done through a helper class. Some sample 
code for this is given below. I have not yet fully explored this solution, I 
hope I won't face any nasty surprises.
Martin
#include <boost/iterator/iterator_adaptor.hpp>
template<class GetsAccess> class FriendHelper;
//non-const Iterator that will be disguised as const iterator,
//only ContainerAdaptor will get access to the real iterator
template <class Iterator, class ContainerAdaptor>
class const_iter
        :public boost::iterator_adaptor<
        const_iter<Iterator, ContainerAdaptor>,
        //a std iterator
        Iterator, 
        //the type that the iterator points to, but constified
        const typename Iterator::value_type
	>
{
public:
        const_iter()
        : const_iter::iterator_adaptor_() {}
        explicit const_iter(const Iterator& p)
                : const_iter::iterator_adaptor_(p) {}
protected:
        //provide access to the underlying iterator to the 
        //ContainerAdaptor
        friend class FriendHelper< ContainerAdaptor >;
        const_iter<Iterator, ContainerAdaptor> const& base() const
        { return base(); }
};
//the ContainerAdaptor gets access to the constiter base function
template<class ContainerAdaptor> class FriendHelper
{
        typedef typename ContainerAdaptor::constiter_type constiter_type;
public:
        constiter_type const& base( const constiter_type& constit )
        { return constit.base(); }
};
//sketch of an adaptor to map 
class mymap{
private:
        friend class FriendHelper<mymap>;
        typedef std::map<int, int> mymap_type;
        typedef const_iter<mymap_type::iterator, mymap > constiter_type; 
public:
        void dosomething()
        {
                mymap_type testmap;
                constiter_type mit(testmap.begin());
                //access the underlying operator through FriendHelper
                FriendHelper<mymap>().base(mit);
        }
};