Skip to content

Instantly share code, notes, and snippets.

@usagi
Last active February 3, 2017 08:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usagi/b6e6fbdb9024b98d9073977b49c3de2f to your computer and use it in GitHub Desktop.
Save usagi/b6e6fbdb9024b98d9073977b49c3de2f to your computer and use it in GitHub Desktop.
picojson の value, array, object の生成を簡単にするヘルパーライブラリーの実装例 ref: http://qiita.com/usagi/items/fa09b3881979b923e3a6
#pragma once
#include <picojson.h>
#include <string>
namespace usagi::json::picojson
{
using object_type = ::picojson::object;
using array_type = ::picojson::array;
using value_type = ::picojson::value;
using null_type = ::picojson::null;
using number_type = double;
using string_type = std::string;
}
/// @file
/// @brief 任意の何かから value_type を"生成"する make_value さん群
#pragma once
#include "type.hxx"
namespace usagi::json::picojson
{
static inline auto make_value( ) -> value_type { return value_type(); }
static inline auto make_value( const null_type ) -> value_type { return make_value(); }
static inline auto make_value( const value_type& in ) -> value_type { return value_type( in ); }
static inline auto make_value( value_type&& in ) -> value_type { return std::move( in ); }
static inline auto make_value( const array_type& in ) -> value_type { return value_type( in ); }
static inline auto make_value( array_type& in ) -> value_type { return value_type( std::move( in ) ); }
static inline auto make_value( const object_type& in ) -> value_type { return value_type( in ); }
static inline auto make_value( object_type&& in ) -> value_type { return value_type( std::move( in ) ); }
static inline auto make_value( const char* in ) -> value_type { return value_type( in ); }
static inline auto make_value( const std::string& in ) -> value_type { return value_type( in ); }
static inline auto make_value( std::string&& in ) -> value_type { return value_type( std::move( in ) ); }
static inline auto make_value( const bool in ) -> value_type { return value_type( in ); }
template < typename T >
static inline auto make_value
( const T v
) -> value_type
{ return value_type( static_cast< double >( v ) ); }
}
auto a = make_array( 1.23f, 1.23, 123, "hoge", "fuga"s, some_value, some_array, some_object, ... );
auto v = make_array_value( ... );
#pragma once
#include "make_value.hxx"
namespace usagi::json::picojson
{
namespace detail
{
template < typename T >
static inline decltype( auto ) emplace_back
( array_type& a, const T& v )
{
a.emplace_back( make_value( v ) );
return a;
}
static inline decltype( auto ) make_array_internal( array_type& a )
{
return a;
}
template < typename HEAD, typename ... TAIL >
static inline decltype( auto ) make_array_internal
( array_type& a, const HEAD& v, const TAIL& ... vs )
{
return make_array_internal( emplace_back( a, v ), vs ... );
}
}
template < typename ... TS >
static inline auto make_array
( const TS& ... vs )
{
array_type a;
return detail::make_array_internal( a, vs ... );
}
template < typename ... TS >
static inline auto make_array_value
( const TS& ... vs )
{
return value_type( make_array( vs ... ) );
}
}
auto o =
make_object
( "f", 1.23f
, "d", 1.23
, "i", 123
, "c", "hoge"
, "s", "fuga"s
, "v", some_value
, "a", some_array
, "o", some_object
, "some_key", something
, ...
);
auto v = make_object_value( ... );
#pragma once
#include "make_value.hxx"
namespace usagi::json::picojson
{
namespace detail
{
template < typename T >
static inline decltype( auto ) emplace
( object_type& o, const std::string& k, const T& v )
{
o.emplace( k, make_value( v ) );
return o;
}
static inline decltype( auto ) make_object_internal( object_type& o )
{
return o;
}
template < typename HEAD, typename ... TAIL >
static inline decltype( auto ) make_object_internal
( object_type& o, const std::string& k, const HEAD& v, const TAIL& ... vs )
{
return make_object_internal( emplace( o, k, v ), vs ... );
}
}
template < typename ... TS >
static inline auto make_object( const TS& ... vs )
{
object_type o;
return detail::make_object_internal( o, vs ... );
}
template < typename ... TS >
static inline auto make_object_value
( const TS& ... vs )
{
return value_type( make_object( vs ... ) );
}
}
#include <usagi/json/picojson/make_array.hxx>
#include <usagi/json/picojson/make_object.hxx>
#include <iostream>
auto main() -> int
{
using namespace std;
using namespace usagi::json::picojson;
std::cout
<< "f: " << make_value( 1.23f ) << '\n'
<< "d: " << make_value( 1.23 ) << '\n'
<< "i: " << make_value( 123 ) << '\n'
<< "n: " << make_value( ) << '\n'
<< "b: " << make_value( true ) << '\n'
<< "s: " << make_value( string( "hoge" ) ) << '\n'
<< "c: " << make_value( "hoge" ) << '\n'
<< "v: " << make_value( make_value( "hoge" ) ) << '\n'
<< "a: " << make_array_value( "hoge", string( "fuga" ), 1.23f, 1.23, 123, null_type(), make_array( 1,2,3 ) ) << '\n'
<< "o: " << make_object_value( "f", 1.23f, "d", 1.23, "i", 123, "n", null_type(), "a", make_array( 1,2,3 ), "o", make_object( "a", 1 ) ) << '\n'
;
}
f: 1.2300000190734863
d: 1.23
i: 123
n: null
b: true
s: "hoge"
c: "hoge"
v: "hoge"
a: ["hoge","fuga",1.2300000190734863,1.23,123,null,[1,2,3]]
o: {"a":[1,2,3],"d":1.23,"f":1.2300000190734863,"i":123,"n":null,"o":{"a":1}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment