あめだまふぁくとりー

Boost.Graphとかできますん

ぷっとも関数おぶじぇくと

プロパティマップを関数オブジェクトに変換するproperty_map_functionはSTLやboostのアルゴリズム,イテレータを使う際大変便利.でもこれはgetはできてもputができない.getのときはアルゴリズムでputのときはループ回すとかやだ!get,putは大抵関数テンプレートだからBoost.Bind,Boost.Lambdaもちょっと使いにくい.なのでちょっと作ってみた↓

#include <boost/property_map/property_map.hpp>

template <class PutPropMap, class GetPropMap>
  class put_property_map_function {
    PutPropMap put_pm;
    GetPropMap get_pm;
    typedef typename boost::property_traits<PutPropMap>::key_type param_type;
    public:
    put_property_map_function(const PutPropMap& ppm, const GetPropMap& gpm)
      : put_pm(ppm), get_pm(gpm) {}
    typedef void result_type;
    result_type operator()(const param_type& k) const
    {
      put(put_pm, k, get(get_pm, k));
    }
  };

template <class PutPropMap, class GetPropMap>
  inline put_property_map_function<PutPropMap, GetPropMap>
  make_put_prop_map_func(PutPropMap ppm, GetPropMap gpm)
  {
    return put_property_map_function<PutPropMap, GetPropMap>(ppm, gpm);
  }

↓のように使える.for_eachの登場数が一気に上がるぜ!

#include <iostream>
#include <boost/graph/adjacency_list.hpp>

int main()
{
  typedef property<edge_weight_t, double> EdgeProp;
  typedef 
    adjacency_list<vecS, vecS, directedS, no_property, EdgeProp>
    Graph;
  Graph g;
  // 以下省略

  // 枝の重みの初期化
  for_each(edges(g).first, edges(g).second,
    make_put_prop_map_func
    (get(edge_weight, g), static_property_map<double>(3.0)));

  // ExteriorMapという外部プロパティマップがあったとして
  // その初期化
  ExteriorMap exterior_map;
  for_each(edges(g).first, edges(g).second,
    make_put_prop_map_func(exterior_map, get(edge_weight, g));
}

なんで第二引数もプロマティマップにしたのかは自分でも覚えてない.まぁ定数はstatic_property_map,constant_property_mapがあるからいいよね!あとは関数(オブジェクト)をプロパティマップに見立てるアダプタが欲しいところ.いつかつくろ.

ん,C++11のλ?C++03を使うことを強いられているんだッ!(集中線)