From: xiaolinzi0941@hotmail.com
To: jsoncpp-devel@lists.sourceforge.net
Subject: Powerful Json::Path
Date: Tue, 1 Apr 2014 09:54:45 +0000

Json::Value v;
v["a"]["b"][0u] = 1;

Json::Path p("a.b.c");
const Json::Value &ref = p.resolve(v);// assert

The above code with course an assert when call "resolve".
That is because "resolve" do not process except conditions.

const Value &
Path::resolve( const Value &root ) const
{
   const Value *node = &root;
   for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
   {
      const PathArgument &arg = *it;
      if ( arg.kind_ == PathArgument::kindIndex )
      {
         if ( !node->isArray()  ||  node->isValidIndex( arg.index_ ) )
         {
            // Error: unable to resolve path (array value expected at position...
         }
         node = &((*node)[arg.index_]);
      }
      else if ( arg.kind_ == PathArgument::kindKey )
      {
         if ( !node->isObject() )
         {
            // Error: unable to resolve path (object value expected at position...)
         }
         node = &((*node)[arg.key_]);
         if ( node == &Value::null )
         {
            // Error: unable to resolve path (object has no member named '' at position...)
         }
      }
   }
   return *node;
}


Users call "resolve" means they must take the risk of fatal error.
so "Path" is useless. But Json::Path should be more powerfull.
Suppose we have a function named "bad" in class Value, which specified the value itself is bad. User shall check it like below:

Json::Value v;
v["a"]["b"][0u] = 1;

Json::Path p("a.b.c");
const Json::Value &ref = p.resolve(v);// will not assert

if (ref.bad())
{
    std::cout << "ref is bad." << std::endl;
    ref = 2; // any operation to bad value will cause assert
}

all we need to do is two step:
1,declare a static member in Json::Value:
static Value bad;
bool bad() const
{
 return &bad == this;
}
2,replace each "// Error: *" line to 
return Value::bad;


further more
we could use Json::Path to resolve the exact type value, Like this:

Json::Value v;
v["a"]["b"][0u] = 1;

Json::Path p("a.b[0]");
Json::Integer i = p.resolveInt(v);

if (i.bad())
{
//do something
}

Wish this features will be added to new version.