Получение первых M элементов вектора mpl - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть boost::mpl::vector с N элементами, скажем:

typedef boost::mpl::vector<int,float,double,short,char> my_vector;

Я хочу получить последовательность, содержащую первые M элементов my_vector.Поэтому, если M равно 2, я хочу получить:

typedef boost::mpl::vector<int,float> my_mvector;

Изначально я думал об использовании erase<s,first,last>, но не смог определить подходящие параметры шаблона для first и last.(Я использовал at_c<...>::type.) Однако я также понимаю, что filter_view также можно использовать для этой задачи.Как лучше всего это сделать?

1 Ответ

3 голосов
/ 15 ноября 2011

Стереть - разумное решение вашей проблемы.

  • Значение, которое вы хотите получить первым, является результатом mpl::begin<T>, который увеличивается на число элементов, которые вы хотите вернуть.
  • Значение, которое вы хотите для конца, является результатом mpl::end<T>

В приведенном ниже коде предполагается, что вы хотите, чтобы мета-функция возвращала исходный тип, если число элементов в векторе меньше запрошенного числа. Также можно использовать статическое утверждение, чтобы проверить, что тип входного интеграла меньше или равен размеру вектора.

Я предоставил first_n_elements, который принимает целочисленную константу MPL, и first_n_elements_c, который просто принимает целое число.

Вы также можете использовать iterator_range<> вместе с итераторами begin и cut в приведенном ниже коде, если вы хотите использовать представление. Я не уверен, каковы преимущества одного над другим в этом случае.

#include <boost/mpl/vector.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/less.hpp>
namespace mpl = boost::mpl;



namespace detail 
{
  // Note, this is an internal detail.  Please use the structures below
  template <typename T, typename N>
  struct erase_after_n
  {
    typedef typename mpl::begin<T>::type begin_iter;
    typedef typename mpl::advance<begin_iter, N>::type cut_iter;
    typedef typename mpl::end<T>::type end_iter;

    typedef 
    typename mpl::erase< T,cut_iter, end_iter >::type type;

  };

}


template <typename T, typename N> 
struct first_n_elements
{
  typedef 
  typename mpl::eval_if< mpl::less < mpl::size<T>, N >,
             T,
             detail::erase_after_n<T, N> >::type type;

};

template <typename T, int N> 
struct first_n_elements_c
{
  typedef 
  typename first_n_elements<T, mpl::int_<N> >::type type ;

};
...