picojson::value を bool へ ECMA-262 互換で変換する実装例

# 概要

[picojson](https://github.com/kazuho/picojson/) の picojson::value を ECMA-262 で `Boolean( x )` するのと互換の boolean 判定結果を `bool` で得る実装例を示したい。

# 実装例

- https://github.com/usagi/usagi/blob/master/include/usagi/json/picojson/to_bool.hxx
    - https://github.com/usagi/usagi/blob/master/include/usagi/json/picojson/type.hxx

```c++
#pragma once

#include "type.hxx"

namespace usagi::json::picojson
{
  static inline auto to_bool( const boolean_type in ) { return in; }
  
  /// @note ECMA-262 NaN: Boolean( 0/0 ) -> false
  /// @note ECMA-262 +Inf: Boolean( +1/0 ) -> true
  /// @note ECMA-262 -Inf: Boolean( -1/0 ) -> true
  static inline auto to_bool( const number_type in )
  {
    return not std::isnan( in ) and in != 0;
  }
  
  /// @note ECMA-262 empty-string: Boolean( "" ) -> false
  static inline auto to_bool( const string_type& in )
  {
    return not in.empty();
  }
  
  /// @note: ECMA-262 array: Boolean( [] ) -> true
  static inline auto to_bool( const array_type& )
  { return true; }
  
  /// @note: ECMA-262 object: Boolean( {} ) -> true
  static inline auto to_bool( const object_type& )
  { return true; }
  
  /// @note: ECMA-262 null: Boolean( null ) -> false
  static inline auto to_bool( const null_type& = null_type() )
  { return false; }
  
  /// @brief ECMA-262 Boolean( in ) 互換変換
  static inline auto to_bool( const value_type& in )
  {
    if ( in.is< boolean_type >() )
      return to_bool( in.get< boolean_type >() );
    
    if ( in.is< number_type >() )
      return to_bool( in.get< number_type >() );
    
    if ( in.is< string_type >() )
      return to_bool( in.get< string_type >() );
    
    if ( in.is< array_type >() )
      return to_bool( in.get< array_type >() );
    
    if ( in.is< object_type >() )
      return to_bool( in.get< object_type >() );
    
    if ( in.is< null_type >() )
      return to_bool();
    
    return false;
  }
  
  /// @brief to_bool した結果を value_type で得る syntax sugar
  static inline auto to_bool_value( const value_type& in )
  { return value_type( to_bool( in ) ); }
}
```

# 使用例

```c++
#include "make_value.hxx"
#include "to_bool.hxx"

#include <iostream>
#include <cmath>

auto main() -> int
{
  using namespace std;
  using namespace usagi::json::picojson;

  cout
    << "null -> " << boolalpha << to_bool( make_value() ) << '\n'
    << "0 -> " << boolalpha << to_bool( make_value( 0 ) ) << '\n'
    << "1 -> " << boolalpha << to_bool( make_value( 1 ) ) << '\n'
    << "-1 -> " << boolalpha << to_bool( make_value( -1 ) ) << '\n'
    << "\"\" -> " << boolalpha << to_bool( make_value( "" ) ) << '\n'
    << "\"hoge\" -> " << boolalpha << to_bool( make_value( "hoge" ) ) << '\n'
    << "false -> " << boolalpha << to_bool( make_value( false ) ) << '\n'
    << "true -> " << boolalpha << to_bool( make_value( true ) ) << '\n'
    << "[] -> " << boolalpha << to_bool( make_array_value() ) << '\n'
    << "{} -> " << boolalpha << to_bool( make_object_value() ) << '\n'
    ;
}
```

- note: `make_value`, `make_array_value`, `make_object_value` -> [picojson の value, array, object の生成を簡単にするヘルパーライブラリーの実装例](http://qiita.com/usagi/items/fa09b3881979b923e3a6)

## 実行結果

```hs
null -> false
0 -> false
1 -> true
-1 -> true
"" -> false
"hoge" -> true
false -> false
true -> true
[] -> true
{} -> true
```