Boost logo

Boost Users :

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);
        }
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net