2015年11月16日月曜日

boost::property_tree::ptree へ array な子要素を放り込む際の tip

boost の ptree を使って "hoge.fuga.piyo": [ 1,2,3,4,5,6,7 ] のような複数階層構造の key へ array な値を放り込みたいとする。地味にめんどくさい。

#include <iostream>
#include <vector>
#include <cstdlib>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

auto main() -> int
{
  using boost::property_tree::ptree;

  // これに "hoge.fuga.piyo: [1,2,3,4,5,6,7]" を突っ込みたいとする。キーが無い場合のほか、更新動作にも対応したいとする。
  ptree pt;

  const std::string key = "hoge.fuga.piyo";
  const std::vector< float > vs{1,2,3,4,5,6,7};

  {
    // これに [1,2,3,4,5,6,7] の部分を先ず作る
    ptree array;
    for ( auto v : vs )
    {
      // array の要素1つ分を作って array へ入れる
      ptree element;
      element.put("", v );
      array.push_back( std::make_pair( "", element ) );
    }
    // key を分割
    const auto split_position = key.rfind(".");
    const std::string sub_keys     = key.substr( 0, split_position );
    const std::string sub_key_tail = key.substr( split_position + 1 );
    // このputで`sub_keys`が存在しない場合、`sub_keys`はあるが`sub_key_tail`が存在しない場合、`sub_key`に`sub_key_tail`が存在する場合の何れでも"巧く"(楽に)対応できる
    pt.put( key, 0 );
    // このeraseで新規であれ更新であれ古いあるいはputにより重複となるkeyを消す
    pt.get_child( sub_keys ).erase( sub_key_tail );
    // それから "hoge.fuga.piyo" へ "[1,2,3,4,5,6,7]"を放り込む
    pt.add_child( key, array );
  }

  write_json("result.json", pt);

  system("cat result.json");
}

0 件のコメント:

コメントを投稿