Ken
Ken

Reputation: 719

C++ friend each class in a boost::mpl::vector

How can I have a class friend each class in a boost::mpl::vector? ie, something that expands to:

template <typename mpl_vector>
class A {
    friend class mpl_vector[0];
    friend class mpl_vector[1];
    ...
    friend class mpl_vector[n];
};

Upvotes: 4

Views: 165

Answers (2)

Andr&#233;s Senac
Andr&#233;s Senac

Reputation: 851

I think you need to use something like Boost.Preprocessor or Pump, to specialize your template for MPL vector of different sizes. Or just to specialize it manually.

You have to specialize your template by this way:

template< typename mpl_vector, std::size_t size = boost::mpl::size< mpl_vector >::type::value >
class A;

template< typename mpl_vector >
class A< mpl_vector, 0 >
{
};

template< typename mpl_vector >
class A< mpl_vector, 1 >
{
    friend class boost::mpl::at< mpl_vector, boost::mpl::int_< 0 > >::type;
};

Upvotes: 2

Pete
Pete

Reputation: 4812

Doing it with boost preprocessor, as suggested by Andres will work.

I tried it out, and it is not nice and will be inefficient to compile. It also is limited to working up to the BOOST_MPL_LIMIT_VECTOR_SIZE. If his method works then it is maybe a bit cleaner.

classA.h:

#if BOOST_PP_IS_ITERATING
friend get_elem<mpl_vector, BOOST_PP_ITERATION()>::type;
#else
#ifndef SOME_INCLUSION_GUARD_H
#define SOME_INCLUSION_GUARD_H

#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>

class Dummy {};
template <int Exists> struct get_elem_i {
    template <typename V, int N> struct get {
        //typedef Dummy type;
        typedef typename boost::mpl::at< V, boost::mpl::int_<N> >::type type;
    };
};
template <> struct get_elem_i<0> {
    template <typename V, int N> struct get {
        typedef Dummy type;
    };
};

template <typename V, int N> struct get_elem {
    typedef typename boost::mpl::size<V>::type size;
    typedef get_elem_i<N < size::value> elem;
    typedef typename elem::get<V, N>::type type;
    //typedef Dummy type;
};

template <typename mpl_vector>
class A {

#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_MPL_LIMIT_VECTOR_SIZE, "classA.h"))
??=include BOOST_PP_ITERATE()

private:
    int test_;
};

#endif // SOME_INCLUSION_GUARD_H
#endif

This file includes itself, so be sure to have the same name as the file in the BOOST_PP_ITERATION_PARAMS_1 bit.

Additionally this code will also cause the class 'Dummy' to be a friend of 'A'.

Upvotes: 3

Related Questions