寻找Boost转换迭代器的复合特征模式

Looking for a composite traits pattern for boost's transform iterators

本文关键字:复合 特征 模式 迭代器 Boost 转换 寻找      更新时间:2023-10-16

设置

当您想让迭代器在返回之前迭代的迭代器时,boost::transform_iterator就非常好。您通过它们传递了一个单一函数,该功能会转换基础迭代器的operator*()的结果,然后转换迭代器返回:

template<typename Map>
struct iterator_transform_traits_map_second {
  typedef typename Map::value_type    value_type;
  typedef typename Map::mapped_type   result_type;
        result_type& operator()(      value_type& v) const {return v.second;}
  const result_type& operator()(const value_type& v) const {return v.second;}
};
typedef 
    boost::transform_iterator<iterator_transform_traits_map_second> 
    transformed_iterator;

到目前为止,一切都很好。但是。

什么搞乱导致

您的同事喜欢这种闪亮的新工具,也开始使用它,很快有人在标题中收集到到目前为止您所提出的一切。这是我们的:

  • iterator_transform_traits_map_first
  • iterator_transform_traits_map_second
  • iterator_transform_traits_map_deref(取消任何容器的条目)
  • iterator_transform_traits_map_deref_second(删除地图条目的second
  • iterator_transform_traits_map_dynamic_cast(执行dynamic_cast<>()任何容器的条目)
  • iterator_transform_traits_map_any_second(在地图条目的second上执行any_cast<>()

当然,这会遗漏许多有用的(因为还没有人需要它们),并且它根本不扩展/strong> 。我刚刚被任命编写一个迭代器,该迭代器会删除地图条目的second并执行dynamic_cast<>(),而我是我被拒绝只添加iterator_transform_traits_map_dynamic_cast_deref_second并继续前进的人。

我想要的

相反,我正在尝试编写一些基本特征和一个编译时组成特征,允许将其中的几个命名为模板参数,然后简单地将其命名。理想情况下,我想要这样的东西:

typedef 
    boost::transform_iterator< 
        iterator_transform_traits< iter_transf_tr_second
                                 , iter_transf_tr_deref
                                 , iter_transf_tr_dynamic_cast<derived>
                                 >
                             > 
    transformed_iterator;

我当前的想法是递归得出包装模板,并递归地调用所有特征,将输出从一个传递到下一个。十年前,我已经做了这样的事情,并且对如何做到这一点有一个基本想法。但是,我上次这样做的是步行。也就是说,我自己实现了所有模板元魔术。

当然,这很愚蠢,鉴于我们现在有了boost.mpl,boost.fusion等,所以我宁愿使用已经存在的东西。但是,在修补了一个下午之后,很明显,在完成此操作之前,我会有很多东西要学习。虽然我不反对学习所有这些,但我有一个喜欢我所做的事情的人,但他说他还是需要拉插头,因为有这个截止日期...我现在可以选择只有编写该死的iterator_transform_traits_map_dynamic_cast_deref_second,复制许多已经腐烂了十年并建立在此上的代码,或提出一个干净的解决方案。

那是您进来的地方。

问题

您将如何实现此复合特征,以利用已经存在的内容?

平台

但是,有一个问题:我们在一个嵌入式平台上,并使用GCC 4.1.2,这意味着 c 03 tr1 boost 1.52 。没有可变模板参数,没有decltype和所有那些花哨的东西。

您去这里:

iterator_transform_traits.hpp

#include <boost/mpl/vector.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/container/vector/convert.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/ref.hpp>
template<typename IteratorTraitsSequence, typename Container>
class   iterator_transform_traits
{
  public:
    struct type
    {
    private:
        struct plcaholder_resolver
        {
          template<typename IteratorTraits, typename IteratorLambda>
          struct apply
          {
            typedef typename boost::mpl::push_back<IteratorTraits,
            typename boost::mpl::apply<typename boost::mpl::lambda<IteratorLambda>::type, typename boost::mpl::back<IteratorTraits>::type::result_type>::type>::type type;
          };
        };
        struct begin_value
        {
            typedef typename Container::value_type   result_type;
        };
        typedef typename boost::mpl::pop_front<typename boost::mpl::fold<IteratorTraitsSequence, boost::mpl::vector<begin_value>, plcaholder_resolver>::type>::type iterator_traits;
    public:
        typedef typename boost::mpl::front<iterator_traits>::type::value_type value_type;
        typedef typename boost::mpl::back<iterator_traits>::type::result_type result_type;
    public:
        struct recursive_iterator_modifier
        {
          template<class> struct result;
          template<class F, typename CurrentResult, typename IteratorTrait>
          struct result<F(CurrentResult&, const IteratorTrait&)> 
          {
              typedef typename IteratorTrait::result_type& type;
          };
          template<class F, typename CurrentResult, typename IteratorTrait>
          struct result<F(const CurrentResult&, const IteratorTrait&)> 
          {
              typedef const typename IteratorTrait::result_type& type;
          };
          template<class F, typename CurrentResult, typename IteratorTrait>
          struct result<F(const boost::reference_wrapper<CurrentResult>&, const IteratorTrait&)> 
          {
              typedef typename IteratorTrait::result_type& type;
          };

          template<typename CurrentResult, typename IteratorTrait>
          typename IteratorTrait::result_type&
          operator()(CurrentResult& modified, const IteratorTrait& it)
          {
              return (it(modified));
          }
          template<typename CurrentResult, typename IteratorTrait>
          const typename IteratorTrait::result_type&
          operator()(const CurrentResult& modified, const IteratorTrait& it)
          {
              return (it(modified));
          }
          template<typename CurrentResult, typename IteratorTrait>
          typename IteratorTrait::result_type&
          operator()(const boost::reference_wrapper<CurrentResult>& modified, const IteratorTrait& it)
          {
              return (it(modified.get()));
          }
        };
    public:
        result_type& operator()(value_type& v) const 
        {
            return boost::fusion::fold(iterator_traits_vector_, boost::ref(v), recursive_iterator_modifier());
        }
        const result_type& operator()(const value_type& v) const 
        {
            return boost::fusion::fold(iterator_traits_vector_, boost::ref(v), recursive_iterator_modifier());
        }

    private:
        typedef typename boost::fusion::result_of::as_vector<iterator_traits>::type  iterator_traits_vector;
        iterator_traits_vector  iterator_traits_vector_;
    };
};

您像这样使用它:

#include <map>
#include <string>
#include <iostream>
#include <typeinfo>
#include "iterator_transform_traits.hpp"
template<typename Pair>
struct iterator_transform_traits_map_second {
  typedef Pair    value_type;
  typedef typename Pair::second_type   result_type;
        result_type& operator()(      value_type& v) const {return v.second;}
  const result_type& operator()(const value_type& v) const {return v.second;}
};
template<typename Dereferenced>
struct iterator_transform_traits_deref {};
template<typename Dereferenced>
struct iterator_transform_traits_deref<Dereferenced*> {
  typedef Dereferenced*    value_type;
  typedef Dereferenced   result_type;
        result_type& operator()(      value_type& v) const {return *v;}
  const result_type& operator()(const value_type& v) const {return *v;}
};

typedef std::map<std::string, std::string*>  string_ptr_map;
typedef iterator_transform_traits<boost::mpl::vector<iterator_transform_traits_map_second<boost::mpl::_1>, iterator_transform_traits_deref<boost::mpl::_1> >, string_ptr_map>::type Transformer;
typedef boost::transform_iterator<Transformer, string_ptr_map::iterator> string_ptr_map_second_deref_iterator;

int main()
{
    string_ptr_map  map;
    map["key1"] = new std::string("value1");
    map["key2"] = new std::string("value2");
    map["key3"] = new std::string("value3");
    for(string_ptr_map_second_deref_iterator it(map.begin(), Transformer()), ite(map.end(), Transformer()); it != ite; ++it)
    {
        std::cout << *it << std::endl;
    }
    return 0;
}

现在一些信息:

  • 每个iterator_transform_trait必须在value_type上模板,他将作为参数而不是在容器上接收,否则您无法自动链接它们。
  • 使用boost::mplboost::fusion有很多很少的元编程操作,我希望元功能名称足够明确,随时提出任何问题
  • 您需要使用mpl序列作为模板参数,因为您无法访问C 11和Variadic模板。
  • 这是一个在线编译版本:http://rextester.com/ziyg56999
  • 这是一个有趣的练习,使我感到头疼:)