Created
January 31, 2017 10:17
-
-
Save usagi/cf8c73d8ecdca64bc4573c9d3d16a951 to your computer and use it in GitHub Desktop.
文字列のパスから picojson::object による階層構造に picojson::value を放り込む例 ref: http://qiita.com/usagi/items/2564e7f660c83793cfc3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// @brief object_type に対しドット区切りのパスで object_type の階層を必要なら作成しながら辿り末梢の要素の参照を返す | |
static inline decltype( auto ) make_object_path | |
( object_type& root_object | |
, const std::string& dot_separated_path | |
) | |
{ | |
// (1) ドット区切りのパス文字列を階層ごとに分離する機能 | |
std::vector< std::string > path; | |
boost::split( path, dot_separated_path, boost::is_any_of( "." ) ); | |
// (2) 分離されたパスの階層構造を組み立てる機能 | |
auto peripheral = &root_object; | |
// 終端のパスを取り出しておく | |
const auto last_path = std::move( path.back() ); | |
path.pop_back(); | |
// 終端の手前のパスまで object を掘る | |
for ( const auto& path_part : path ) | |
{ | |
const auto i = peripheral->find( path_part ); | |
// note: 末梢に必要なパスが無いか object ではない場合にのみ object を作成 | |
if ( i == peripheral->cend() or not i->second.is< object_type >() ) | |
(*peripheral)[ path_part ] = value_type( object_type() ); | |
// note: root_object から末梢側へ1段階辿る | |
peripheral = &(*peripheral)[ path_part ].get< object_type >(); | |
} | |
// 終端の value& を返す | |
return (*peripheral)[ last_path ]; | |
} | |
} | |
/// @brief element_value が rvalue の場合向けの set_value | |
static inline auto set_value | |
( object_type& root_object | |
, const std::string& dot_separated_path | |
, value_type&& element_value | |
) | |
{ detail::make_object_path( root_object, dot_separated_path ) = std::move( element_value ); } | |
/// @brief object_type に対しドット区切りのパスで object_type の階層を辿り value_type を放り込む | |
static inline auto set_value | |
( object_type& root_object | |
, const std::string& dot_separated_path | |
, const value_type& element_value | |
) | |
{ detail::make_object_path( root_object, dot_separated_path ) = element_value; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// @brief value_type へ可換な T 型の値に対応する set_value の syntax sugar ラッパー | |
template < typename T = null_type > | |
static inline auto set_value( object_type& root_object, const std::string& dot_separated_path, const T& element_value = T() ) | |
{ set_value( root_object, dot_separated_path, value_type( static_cast< double >( element_value ) ) ); } | |
template < > | |
inline auto set_value< null_type >( object_type& root_object, const std::string& dot_separated_path, const null_type& ) | |
{ set_value( root_object, dot_separated_path, value_type() ); } | |
template < > | |
inline auto set_value< array_type >( object_type& root_object, const std::string& dot_separated_path, const array_type& element_value ) | |
{ set_value( root_object, dot_separated_path, value_type( element_value ) ); } | |
template < > | |
inline auto set_value< object_type >( object_type& root_object, const std::string& dot_separated_path, const object_type& element_value ) | |
{ set_value( root_object, dot_separated_path, value_type( element_value ) ); } | |
template < > | |
inline auto set_value< value_type >( object_type& root_object, const std::string& dot_separated_path, const value_type& element_value ) | |
{ set_value( root_object, dot_separated_path, element_value ); } | |
template < > | |
inline auto set_value< std::string >( object_type& root_object, const std::string& dot_separated_path, const std::string& element_value ) | |
{ set_value( root_object, dot_separated_path, value_type( element_value ) ); } | |
static inline auto set_value( object_type& root_object, const std::string& dot_separated_path, const char* element_value ) | |
{ set_value( root_object, dot_separated_path, value_type( element_value ) ); } | |
static inline auto set_value( object_type& root_object, const std::string& dot_separated_path, const bool element_value ) | |
{ set_value( root_object, dot_separated_path, value_type( element_value ) ); } | |
/// root_value が object_type を内包する value_type の場合に対応する set_value の syntax sugar ラッパー | |
template < typename T = null_type > | |
static inline auto set_value( value_type& root_value, const std::string& dot_separated_path, T&& element_value = T() ) | |
{ set_value( root_value.get< object_type >(), dot_separated_path, std::move( element_value ) ); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <usagi/json/picojson/set_value.hxx> | |
#include <iostream> | |
auto main() -> int | |
{ | |
using namespace std::literals::string_literals; | |
using namespace usagi::json::picojson; | |
object_type a, b; | |
a["hoge"] = value_type( 1.0 ); | |
a["fuga"] = value_type( 2.0 ); | |
value_type va( a ); | |
set_value( va, "aa.bb.xx", 1.23 ); | |
set_value( va, "aa.bb.yy", 1.23f ); | |
set_value( va, "aa.bb.zz", 123ull ); | |
set_value( va, "aa.bb.ww", true ); | |
set_value( va, "aa.cc.ss", "xyz123" ); | |
set_value( va, "aa.cc.tt", "xyz456"s ); | |
set_value( va, "uu.vv" ); | |
set_value( va, "array", array_type() ); | |
set_value( va, "object", object_type() ); | |
std::cout << va; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"aa":{"bb":{"ww":true,"xx":1.23,"yy":1.2300000190734863,"zz":123},"cc":{"ss":"xyz123","tt":"xyz456"}},"array":[],"fuga":2,"hoge":1,"object":{},"uu":{"vv":null}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"aa": { | |
"bb": { | |
"ww": true, | |
"xx": 1.23, | |
"yy": 1.2300000190734863, | |
"zz": 123 | |
}, | |
"cc": { | |
"ss": "xyz123", | |
"tt": "xyz456" | |
} | |
}, | |
"array": [], | |
"fuga": 2, | |
"hoge": 1, | |
"object": {}, | |
"uu": { | |
"vv": null | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment