$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81002 - in trunk/libs/spirit/example/qi/json: . detail parser
From: joel_at_[hidden]
Date: 2012-10-16 23:57:44
Author: djowel
Date: 2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
New Revision: 81002
URL: http://svn.boost.org/trac/boost/changeset/81002
Log:
added json parser contributed by Michael Caisse 
Added:
   trunk/libs/spirit/example/qi/json/
   trunk/libs/spirit/example/qi/json/detail/
   trunk/libs/spirit/example/qi/json/detail/io_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/detail/util_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/detail/value_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/io.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/parser/
   trunk/libs/spirit/example/qi/json/parser/grammar.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/parser/grammar_def.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/util.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/value.hpp   (contents, props changed)
Added: trunk/libs/spirit/example/qi/json/detail/io_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/detail/io_impl.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,208 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ *
+ */
+
+#ifndef CIERE_JSON_IO_IMPL_HPP
+#define CIERE_JSON_IO_IMPL_HPP
+
+#include <string>
+#include <fstream>
+#include <istream>
+#include <ios>
+#include <boost/foreach.hpp>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/support_istream_iterator.hpp>
+
+#include "../io.hpp"
+#include "../parser/grammar.hpp"
+
+namespace ciere { namespace json
+{
+   namespace spirit = boost::spirit;
+
+   namespace detail
+   {
+      struct printer : public boost::static_visitor<>
+      {
+         printer(std::ostream& s) : stream(s) {}
+
+         void operator()(string_t const & utf) const
+         {
+            stream << '"';
+
+            typedef ::boost::uint32_t ucs4_char;
+            typedef boost::u8_to_u32_iterator<std::string::const_iterator> iter_t;
+            iter_t f = utf.begin();
+            iter_t l = utf.end();
+
+            for (iter_t i = f; i != l; ++i)
+            {
+               ucs4_char c = *i;
+               switch (c)
+               {
+                  case 0:       stream << "\\0";  break;
+                  case 0x7:     stream << "\\a";  break;
+                  case 0x8:     stream << "\\b";  break;
+                  case 0x9:     stream << "\\t";  break;
+                  case 0xA:     stream << "\\n";  break;
+                  case 0xB:     stream << "\\v";  break;
+                  case 0xC:     stream << "\\f";  break;
+                  case 0xD:     stream << "\\r";  break;
+                  case 0x1B:    stream << "\\e";  break;
+                  case '"':     stream << "\\\""; break;
+                  case '\\':    stream << "\\\\"; break;
+                  case 0xA0:    stream << "\\_";  break;
+                  case 0x85:    stream << "\\N";  break;
+                  case 0x2028:  stream << "\\L";  break;
+                  case 0x2029:  stream << "\\P";  break;
+                  default:      stream << boost::spirit::to_utf8(c);
+               }
+            }
+
+            stream << '"';
+         }
+
+         template< typename T >
+         void operator()(T const & value) const
+         {
+            stream << value;
+         }
+
+         void operator()(double d) const
+         {
+            // javascript's handling of NaN and +/-Infinity
+            // isn't so great. JSON simply follows the javascript
+            // standard. We can output nan and infinity; however,
+            // we cannot actually parse it back in afaict because
+            // the javascript side is generating a null?
+            //
+            // TODO: clear this up with something definitive
+            if(boost::math::isnan(d))
+            {
+               stream << "NaN";
+               return;
+            }
+            if(boost::math::isinf(d))
+            {
+               if(d < 0.0) { stream << '-'; }
+               stream << "Infinity";
+               return;
+            }
+            stream << d;
+         }
+
+         void operator()(bool_t value) const
+         {
+            stream << (value?"true":"false");
+         }
+
+         void operator()(null_t value) const
+         {
+            stream << "null";
+         }
+
+         void operator()(object_t const & obj) const
+         {
+            stream << "{";
+            bool first = true;
+
+            BOOST_FOREACH( object_t::value_type const & v, obj )
+            {
+               if( first ) { first = false;  }
+               else        { stream << ", "; }
+               
+               stream << '"' << v.first << "\":";
+               boost::apply_visitor( *this,v.second);
+            }
+
+            stream << "}";
+         }
+
+         void operator()(array_t const & arr) const
+         {
+            stream << "[";
+            bool first = true;
+
+            BOOST_FOREACH( value const & v, arr )
+            {
+               if( first ) { first = false;  }
+               else        { stream << ", "; }
+
+               boost::apply_visitor(*this,v);
+            }
+            stream << "]";
+         }
+
+         std::ostream& stream;
+      };
+   }
+
+   inline std::ostream& operator<<(std::ostream& stream, value const & v)
+   {
+      boost::apply_visitor(detail::printer(stream),v);
+      return stream;
+   }
+
+   inline std::istream& operator>>( std::istream& stream, value& object )
+   {
+      if( !json::read( stream, object ) )
+      {
+         stream.setstate( std::ios_base::failbit );
+      }
+
+      return stream;
+   }
+
+   inline bool read( std::istream& stream, value& object)
+   {
+      typedef parser::grammar< spirit::istream_iterator > grammar_t;
+
+      stream.unsetf( std::ios::skipws );
+      spirit::istream_iterator iter( stream );
+      spirit::istream_iterator end_iter;
+      
+      grammar_t grammar;
+      return( spirit::qi::phrase_parse( iter, end_iter,
+                                        grammar,
+                                        spirit::ascii::space_type(),
+                                        object ) );
+   }
+
+   inline bool read( std::string const & filename, value& object)
+   {
+      std::ifstream stream( filename.c_str() );
+      if( !stream.is_open() )
+      {
+         return false;
+      }
+
+      return read( stream, object );
+   }
+
+   inline value construct( std::string const & input )
+   {
+      typedef std::string::const_iterator iter_t;
+      typedef parser::grammar<iter_t> grammar_t;
+
+      grammar_t grammar;
+      json::value value;
+
+      iter_t iter = input.begin();
+      iter_t end =  input.end();
+
+      spirit::qi::phrase_parse( iter, end,
+                                grammar,
+                                spirit::ascii::space_type(),
+                                value );
+
+      return value;
+   }
+}}
+
+#endif // CIERE_JSON_IO_IMPL_HPP
Added: trunk/libs/spirit/example/qi/json/detail/util_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/detail/util_impl.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,40 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ *
+ */
+
+#ifndef CIERE_JSON_UTIL_IMPL_HPP
+#define CIERE_JSON_UTIL_IMPL_HPP
+
+#include "../util.hpp"
+
+namespace ciere { namespace json
+{
+   namespace detail
+   {
+   }
+
+   /**
+    *  Returns true if elements of m match those value.
+    */
+   bool match( value const & value, value const & m )
+   {
+      return false;
+   }
+
+   /**
+    *  Results in : target = target + value
+    */
+   bool combine( value& target, value const & value )
+   {
+      return false;
+   }
+
+}}
+
+#endif // CIERE_JSON_UTIL_IMPL_HPP
Added: trunk/libs/spirit/example/qi/json/detail/value_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/detail/value_impl.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,280 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2012 Jeroen Habraken 
+ *   Copyright (c) 2011 Joel de Guzman
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef CIERE_JSON_VALUE_IMPL_HPP
+#define CIERE_JSON_VALUE_IMPL_HPP
+
+#include <iostream> //test
+
+#include "../value.hpp"
+#include <boost/lexical_cast.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/assert.hpp>
+
+namespace ciere { namespace json
+{
+   namespace detail
+   {
+      template< typename T >
+      struct extract
+      {
+         template<typename A>
+         static T get(A & v)               { return boost::get<T>(v); }
+
+         template<typename A>
+         static const T get(const A & v)   { return boost::get<T>(v); }
+      };
+
+
+      template<typename R>
+      struct convert
+      {
+         BOOST_MPL_ASSERT_MSG(
+              !(boost::is_same<R,null_t>::value)
+            , CANNOT_GET_AS_WITH_NULL_T
+            , (R) 
+            );
+
+         template<typename T>
+         static R apply( T const & v
+                       , typename boost::enable_if<boost::is_convertible<R,T> >::type* dummy=0 )
+         {
+            return v;
+         }
+
+
+         static R apply( string_t const & v )
+         {
+            return boost::lexical_cast<R>(v);
+         }
+
+         template<typename T>
+         static R apply( T const & v
+                       , typename boost::disable_if<boost::is_convertible<R,T> >::type* dummy=0 )
+         {
+            throw get_as_error();
+            return R();
+         }
+      };
+
+      template<>
+      struct convert<string_t>
+      {
+         static string_t apply( string_t const & v)
+         {
+            return v;
+         }
+
+         static string_t apply( float_t const & v )
+         {
+            return boost::lexical_cast<std::string>(v);
+         }
+
+         static string_t apply( int_t const & v )
+         {
+            return boost::lexical_cast<std::string>(v);
+         }
+
+         static string_t apply( bool_t const & v)
+         {
+            return (v ? "true" : "false");
+         }
+
+         static string_t apply( null_t const & )
+         {
+            return "null";
+         }
+
+         template<typename T>
+         static string_t apply( T const & v )
+         {
+            throw get_as_error();
+            return "";
+         }
+      };
+
+
+      template<>
+      struct convert<bool_t>
+      {
+         template<typename T>
+         static bool_t apply( T const & v
+                            , typename boost::enable_if<boost::is_convertible<bool_t,T> >::type* dummy=0 )
+         {
+            return v;
+         }
+
+         static bool_t apply( string_t const & v )
+         {
+            if( v == "true" ) return true;
+            else              return false;
+         }
+
+         template<typename T>
+         static bool_t apply( T const & v 
+                            , typename boost::disable_if<boost::is_convertible<bool_t,T> >::type* dummy=0 )
+         {
+            throw get_as_error();
+            return false;
+         }
+      };
+
+
+      
+      template<typename T>
+      struct convert_to : public boost::static_visitor<T>
+      {
+         template<typename V>
+         T operator()(V const & v) const
+         {
+            try
+            {
+               return convert<T>::apply(v);
+            }
+            catch(...)
+            {
+               throw get_as_error();
+            }
+         }
+
+         // if the types are the same, no conversion required
+         T operator()(T const & v) const
+         {
+            return v;
+         }
+      };
+   }
+
+
+   struct value::make_json_value
+   {
+      json::value&       operator()(json::value& v)       const { return v; }
+      const json::value& operator()(const json::value& v) const { return v; }
+   };
+
+   struct value::make_json_member
+   {
+      value::member       operator()(object_t::value_type & v)       const  { return value::member(v);       }
+      value::const_member operator()(const object_t::value_type & v) const  { return value::const_member(v); }
+   };
+
+
+   // -------------------------------------------------------------------------------
+   //    array handling
+   // -------------------------------------------------------------------------------
+
+   /**
+    *  Add compatible type to the end of the array
+    */
+   template< typename T >
+   value& value::add( T v )
+   {
+      push_back(v);
+      return *this;
+   }
+
+
+   /**
+    *  Add a compatible type to the end of the array, functor style.
+    */
+   template< typename T >
+   value& value::operator()( T v )
+   {
+      return add(v);
+   } 
+
+   /**
+    *  Add compatible type to the end of the array, stl style-ish
+    *  Actually returns a reference the newly added value.
+    */
+   template< typename T >
+   value& value::push_back( T v )
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+      
+      // if we aren't an array, we need to be an array
+      if( !p_array )
+      {
+         base_type::get() = array_t();
+         p_array = boost::get<array_t>(&base_type::get());
+      }
+
+      p_array->push_back( (json::value(v)) );
+      return p_array->back();
+   } 
+
+
+   // -------------------------------------------------------------------------------
+   //    object handling
+   // -------------------------------------------------------------------------------
+
+   template< typename T >
+   value& value::set( string_t const & name, T v )
+   {
+      object_t* p_object = boost::get<object_t>(&base_type::get());
+
+      // if this isn't an object type ... it needs to be
+      if( !p_object )
+      {
+         base_type::get() = object_t();
+         p_object = boost::get<object_t>(&base_type::get());
+      }
+
+      (*p_object)[name] = v;
+      return *this;
+   }
+
+
+   template< typename T >
+   value& value::operator()( string_t const & name, T v )
+   {
+      return set(name,v);
+   }
+
+
+   // -------------------------------------------------------------------------------
+   // Extract based on type
+   // -------------------------------------------------------------------------------
+   template< typename T >
+   T value::get()
+   {
+      return detail::extract<T>::get(base_type::get());
+   }
+
+   template< typename T >
+   const T value::get() const
+   {
+      return detail::extract<T>::get(base_type::get());
+   }
+   // -------------------------------------------------------------------------------
+   // -------------------------------------------------------------------------------
+
+   // -------------------------------------------------------------------------------
+   // Extract based on type and convert to requested type
+   // -------------------------------------------------------------------------------
+   template< typename T >
+   T value::get_as()
+   {
+      return boost::apply_visitor(detail::convert_to<T>(),base_type::get());
+   }
+
+   template< typename T >
+   const T value::get_as() const
+   {
+      return boost::apply_visitor(detail::convert_to<T>(),base_type::get());
+   }
+   // -------------------------------------------------------------------------------
+   // -------------------------------------------------------------------------------
+
+}}
+
+#endif // CIERE_JSON_VALUE_IMPL_HPP
Added: trunk/libs/spirit/example/qi/json/io.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/io.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,45 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ *
+ */
+
+#ifndef CIERE_JSON_IO_HPP
+#define CIERE_JSON_IO_HPP
+
+#include <iostream>
+#include <string>
+#include "value.hpp"
+
+namespace ciere { namespace json
+{
+
+   std::ostream& operator<<(std::ostream& stream, value const & value);
+
+   std::istream& operator>>( std::istream& stream, value& object );
+
+   /**
+    *  Reads from filename and populates object with the contents of the filename.
+    */
+   bool read( std::string const & filename, value& object);
+
+   /**
+    * Read from stream and populate object with json contents
+    */
+   bool read( std::istream& stream, value& object);
+
+   /**
+    * construct a json value from the input string
+    */
+   value construct( std::string const & input );
+
+}}
+
+
+#include "detail/io_impl.hpp"
+
+#endif  // CIERE_JSON_IO_HPP
Added: trunk/libs/spirit/example/qi/json/parser/grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/parser/grammar.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,50 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef CIERE_JSON_DETAIL_GRAMMAR_HPP
+#define CIERE_JSON_DETAIL_GRAMMAR_HPP
+
+#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
+#include <string>
+#include <boost/spirit/include/qi.hpp>
+#include "../value.hpp"
+
+
+namespace ciere { namespace json { namespace parser
+{
+   namespace qi      = boost::spirit::qi;
+   namespace ascii   = boost::spirit::ascii;
+
+   namespace detail
+   {
+      template <typename Iterator>
+      struct unicode_string : qi::grammar<Iterator, std::string()>
+      {
+         unicode_string();
+         qi::rule<Iterator, void(std::string&)> escape;
+         qi::rule<Iterator, void(std::string&)> char_esc;
+         qi::rule<Iterator, std::string()> double_quoted;
+      };
+   }
+
+
+   template< typename Iterator >
+   struct grammar : qi::grammar< Iterator, json::value(), ascii::space_type >
+   {
+      grammar();
+      qi::rule< Iterator, json::value()           , ascii::space_type > value;
+      qi::rule< Iterator, json::object_t()        , ascii::space_type > object;
+      qi::rule< Iterator, json::object_member_t() , ascii::space_type > member_pair;
+      qi::rule< Iterator, json::array_t()         , ascii::space_type > array;
+      detail::unicode_string< Iterator                                > string_value;
+      qi::rule< Iterator, json::null_t()          , ascii::space_type > null_value;
+   };
+
+}}}
+
+#endif  // CIERE_JSON_DETAIL_GRAMMAR_HPP
Added: trunk/libs/spirit/example/qi/json/parser/grammar_def.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/parser/grammar_def.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,174 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (c) 2011 Joel de Guzman
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef CIERE_JSON_DETAIL_GRAMMAR_DEF_HPP
+#define CIERE_JSON_DETAIL_GRAMMAR_DEF_HPP
+
+#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
+#include <string>
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/fusion/adapted/std_pair.hpp>
+#include "grammar.hpp"
+
+
+namespace ciere { namespace json { namespace parser
+{
+
+   namespace qi = boost::spirit::qi;
+   namespace ascii = boost::spirit::ascii;
+   namespace phoenix = boost::phoenix;
+
+   typedef boost::uint32_t uchar; // a unicode code point
+
+   namespace detail
+   {
+      struct push_utf8
+      {
+         template <typename S, typename C>
+         struct result { typedef void type; };
+
+         void operator()(std::string& utf8, uchar code_point) const
+         {
+            typedef std::back_insert_iterator<std::string> insert_iter;
+            insert_iter out_iter(utf8);
+            boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
+            *utf8_iter++ = code_point;
+         }
+      };
+
+      struct push_esc
+      {
+         template <typename S, typename C>
+         struct result { typedef void type; };
+
+         void operator()(std::string& utf8, uchar c) const
+         {
+            switch (c)
+            {
+               case ' ': utf8 += ' ';          break;
+               case '\t': utf8 += '\t';        break;
+               case '0': utf8 += char(0);      break;
+               case 'a': utf8 += 0x7;          break;
+               case 'b': utf8 += 0x8;          break;
+               case 't': utf8 += 0x9;          break;
+               case 'n': utf8 += 0xA;          break;
+               case 'v': utf8 += 0xB;          break;
+               case 'f': utf8 += 0xC;          break;
+               case 'r': utf8 += 0xD;          break;
+               case 'e': utf8 += 0x1B;         break;
+               case '"': utf8 += '"';          break;
+               case '/': utf8 += '/';          break;
+               case '\\': utf8 += '\\';        break;
+
+               case '_': push_utf8()(utf8, 0xA0);  break;
+               case 'N': push_utf8()(utf8, 0x85);  break;
+               case 'L': push_utf8()(utf8, 0x2028);  break;
+               case 'P': push_utf8()(utf8, 0x2029);  break;
+            }
+         }
+      };
+
+
+      template< typename Iterator >
+      unicode_string<Iterator>::unicode_string()
+         : unicode_string::base_type(double_quoted)
+      {
+         qi::char_type char_;
+         qi::_val_type _val;
+         qi::_r1_type _r1;
+         qi::_1_type _1;
+         qi::_2_type _2;
+         qi::lit_type lit;
+         qi::eol_type eol;
+         qi::repeat_type repeat;
+         qi::hex_type hex;
+
+         using boost::spirit::qi::uint_parser;
+         using boost::phoenix::function;
+         using boost::phoenix::ref;
+
+         uint_parser<uchar, 16, 4, 4> hex4;
+         uint_parser<uchar, 16, 8, 8> hex8;
+         function<detail::push_utf8> push_utf8;
+         function<detail::push_esc> push_esc;
+
+         escape =
+                ('x' > hex)                     [push_utf8(_r1, _1)]
+            |   ('u' > hex4)                    [push_utf8(_r1, _1)]
+            |   ('U' > hex8)                    [push_utf8(_r1, _1)]
+            |   char_("0abtnvfre\"/\\N_LP \t")  [push_esc(_r1, _1)]
+            |   eol                             // continue to next line
+            ;
+
+         char_esc =
+            '\\' > escape(_r1)
+            ;
+
+         double_quoted =
+              '"'
+            > *(char_esc(_val) | (~char_('"'))    [_val += _1])
+            > '"'
+            ;
+      }
+
+   }  // end detail
+
+
+   template< typename Iterator >
+   grammar<Iterator>::grammar()
+      : grammar::base_type( value )
+   {
+      qi::_val_type            _val;
+      qi::lit_type             lit;
+      ascii::char_type         char_;
+      qi::double_type          double_;
+      qi::int_parser<int64_t>  int_;
+      qi::bool_type            bool_value;
+      qi::attr_type            attr;
+      qi::lexeme_type          lexeme;
+
+      value =
+           null_value
+         | bool_value
+         | string_value
+         | lexeme[int_ >> !char_(".eE")]
+         | double_
+         | object
+         | array
+         ;
+
+      object =
+            lit('{')
+         >> -(member_pair % ',')
+         >> lit('}')
+         ;
+
+      member_pair =
+            string_value
+         >> ':'
+         >> value
+         ;
+
+      array = 
+            lit('[')
+         >> -(value % ',')
+         >> lit(']')
+         ;
+
+      null_value = 
+            lit("null") 
+         >> attr(json::null_t())
+         ;
+   }
+
+}}}
+
+
+#endif  // CIERE_JSON_DETAIL_GRAMMAR_DEF_HPP
Added: trunk/libs/spirit/example/qi/json/util.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/util.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,32 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ *
+ */
+
+#ifndef CIERE_JSON_UTIL_HPP
+#define CIERE_JSON_UTIL_HPP
+
+#include <iostream>
+#include <string>
+#include "value.hpp"
+
+namespace ciere { namespace json
+{
+   /**
+    *  Returns true if elements of m match those value.
+    */
+   bool match( value const & value, value const & m );
+
+   /**
+    *  Results in : target = target + value
+    */
+   bool combine( value& target, value const & value );
+}}
+
+
+#endif  // CIERE_JSON_UTIL_HPP
Added: trunk/libs/spirit/example/qi/json/value.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/value.hpp	2012-10-16 23:57:41 EDT (Tue, 16 Oct 2012)
@@ -0,0 +1,390 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2012 Jeroen Habraken
+ *   Copyright (C) 2011, 2012 Object Modeling Designs
+ *
+ *   Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#ifndef CIERE_JSON_VALUE_HPP
+#define CIERE_JSON_VALUE_HPP
+
+#include <string>
+#include <boost/variant.hpp>
+#include <boost/exception/all.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/container/stable_vector.hpp>
+#include <boost/spirit/include/support_extended_variant.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/utility/enable_if.hpp>
+
+
+namespace ciere { namespace json
+{
+
+   // ---------------------------------------------------
+   // exceptions
+   // ---------------------------------------------------
+
+   struct not_container_type : virtual boost::exception, virtual std::exception {};
+   struct not_object_type    : virtual boost::exception, virtual std::exception {};
+   struct not_array_type     : virtual boost::exception, virtual std::exception {};
+   struct not_number_type    : virtual boost::exception, virtual std::exception {};
+   struct get_as_error       : virtual boost::exception, virtual std::exception {};
+
+   // ---------------------------------------------------
+   // ---------------------------------------------------
+
+
+   // ------------------- ast types --------------------
+   //
+   typedef std::string                                  string_t;
+   typedef double                                       double_t;
+   typedef double                                       float_t;
+   typedef int64_t                                      int_t;
+   typedef bool                                         bool_t;
+   struct                                               null_t
+   {};
+   class                                                value;
+   typedef std::map<std::string, value>                 object_t;
+   typedef std::pair<std::string, value>                object_member_t;
+   typedef boost::container::stable_vector<value>       array_t;
+
+
+   // nulls always compare
+   inline bool operator==(null_t,null_t) { return true;  }
+   inline bool operator!=(null_t,null_t) { return false; }
+
+   inline std::ostream & operator<<(std::ostream & out, null_t)
+   { out << "null"; return out; }
+
+
+
+   /**
+    *  possible types being stored in the json::value
+    */
+   enum value_types
+   {
+      string_type,
+      double_type,
+      int_type,
+      bool_type,
+      null_type,
+      value_type,
+      object_type,
+      array_type
+   };
+
+
+   /**
+    *
+    *
+    */
+   class value  
+      : public boost::spirit::extended_variant<
+                   null_t
+                 , bool_t
+                 , string_t
+                 , int_t
+                 , double_t
+                 , object_t
+                 , array_t      >
+   {
+      public:
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+         value(null_t val = null_t())     : base_type(val) {}
+         value(bool_t val)                : base_type(val) {}
+         value(string_t const & val)      : base_type(val) {}
+         value(char const * val)          : base_type((string_t(val))) {}
+         value(object_t const & val)      : base_type(val) {}
+         value(array_t const & val)       : base_type(val) {}
+         value(value const & rhs)         : base_type(rhs.get_ast()) {}
+
+         template< typename T >
+         value(T val,
+               typename boost::enable_if<boost::is_floating_point<T> >::type* = 0)
+            : base_type( (double_t(val)) ) {}
+
+
+         template< typename T >
+         value(T val,
+               typename boost::enable_if<
+                   boost::mpl::or_<
+                        boost::is_integral<T>
+                      , boost::is_enum<T>
+                      >
+                  >::type* = 0)
+            : base_type( (int_t(val)) ) {}
+
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+
+         /**
+          *  Returns the type currently being stored
+          */
+         value_types type() const;
+
+
+         // -------------------------------------------------------------------------------
+         //    iterator helpers
+         // -------------------------------------------------------------------------------
+         /**
+          *  type returned from an object iterator
+          */
+         struct member
+         {
+            member(object_t::value_type & m) : member_pair(m) {}
+            
+            std::string         name()  const { return member_pair.first; }
+            json::value &       value()       { return member_pair.second; }
+            json::value const & value() const { return member_pair.second; }
+
+            private:
+               object_t::value_type & member_pair;
+         };
+
+         struct const_member
+         {
+            const_member(object_t::value_type & m)       : member_pair(m) {}
+            const_member(object_t::value_type const & m) : member_pair(m) {}
+
+            std::string         name()  const { return member_pair.first; }
+            const json::value & value() const { return member_pair.second; }
+
+            private:
+               object_t::value_type const & member_pair;
+         };
+
+
+         // -------------------------------------------------------------------------------
+         //    iterator types
+         // -------------------------------------------------------------------------------
+
+      private:
+         struct make_json_value;
+         struct make_json_member;
+
+      public:
+         typedef boost::transform_iterator<  make_json_member
+                                           , object_t::iterator
+                                           , member >                      object_iterator;
+
+         typedef boost::transform_iterator<  make_json_member
+                                           , object_t::const_iterator
+                                           , const_member >                const_object_iterator;
+
+         typedef boost::transform_iterator<  make_json_value
+                                           , array_t::iterator
+                                           , value & >                     array_iterator;
+
+         typedef boost::transform_iterator<  make_json_value
+                                           , array_t::const_iterator
+                                           , value const & >               const_array_iterator;
+
+
+      
+
+         // -------------------------------------------------------------------------------
+         //    iterator access
+         // -------------------------------------------------------------------------------
+
+         /**
+          *  Returns an iterator pointing to the fist member in the object if the value type
+          *  is object_type. Otherwise, throw not_object_type.
+          */
+         object_iterator       begin_object();
+         const_object_iterator begin_object() const;
+
+         /**
+          *  Returns an iterator that can be compared to determine the end of members in an object. If
+          *  the value type is not an object then throw not_object_type.
+          */
+         object_iterator       end_object();
+         const_object_iterator end_object() const;
+
+         /**
+          *  Returns an iterator pointing to the fist member in the array if the value type
+          *  is array_type. Otherwise, throw not_array_type.
+          */
+         array_iterator       begin_array();
+         const_array_iterator begin_array() const;
+
+         /**
+          *  Returns an iterator that can be compared to determine the end of members in an array. If the 
+          *  value type is not array_type throw not_array_type.
+          */
+         array_iterator       end_array();
+         const_array_iterator end_array() const;
+
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+
+
+
+         // -------------------------------------------------------------------------------
+         //    array handling
+         // -------------------------------------------------------------------------------
+
+         /**
+          *  Add compatible type to the end of the array
+          */
+         template< typename T >
+         value & add(T v);
+         value & add(char const * v);
+
+         /**
+          *  Add a compatible type to the end of the array, functor style.
+          */
+         template< typename T >
+         value & operator()(T v);
+
+         /**
+          *  Add compatible type to the end of the array, stl style-ish
+          *  Actually returns a reference the newly added value.
+          */
+         template< typename T >
+         value & push_back(T v);
+         value & push_back(char const * v);
+
+         /**
+          *  Access array element stored at index value. Will throw out_of_range exception
+          *  if index is not a valid index for the container.
+          */
+         value &       at(size_t index);
+         value const & at(size_t index) const;
+
+         /**
+          *  Access array element stored at index value. If the array length is less than
+          *  index, the array will be expanded to index + 1 length and additional
+          *  locations will be filled with null_type.
+          */
+         value &       operator[](int index);
+         value const & operator[](int index) const;
+
+         /**
+          *  Erase removes the value at index. 
+          */
+         value & erase(int index);
+
+
+         /**
+          *  Returns the number of elements stored if the value is holding an array or
+          *  object type. If it is not an array or object type the method throws
+          *  ciere::json::not_array_type
+          */
+         std::size_t length() const;
+
+
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+
+
+         // -------------------------------------------------------------------------------
+         //    object handling
+         // -------------------------------------------------------------------------------
+
+         /**
+          *  Set the member name to value v.
+          *  If member name already exists, its value will be replaced.
+          *
+          *  If the value object is not an object type it will become one.
+          */
+         template< typename T >
+         value & set(string_t const & name, T v);
+
+         // template can be ambigous for some types ... lets get specific
+         value & set(string_t const & name, char const * v);
+
+         /**
+          *  Functor style setting. The first value is the name of the member to add.
+          *  the second value is the value to be set.
+          */
+         template< typename T >
+         value & operator()(string_t const & name, T v);
+
+         /**
+          *  Tests if the object contains the specified named object.
+          */
+         bool has_key(std::string const & key) const;
+
+         /**
+          *  Access the object's member with the specified name.
+          *  If no member exists, one will be created with a default value
+          *  of null_t.
+          */
+         value &       operator[](char const * v);
+         value &       operator[](string_t const & v);
+         value const & operator[](char const * v) const;
+         value const & operator[](string_t const & v) const;
+
+         value & erase(char const * v){ return erase( (string_t(v)) ); }
+         value & erase(string_t const & v);
+
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+
+
+         /**
+          *  Extract the actual value based on the type T. If the json::value
+          *  does not contain type T, the method will throw.
+          */
+         template< typename T >
+         T get();
+
+         template< typename T >
+         const T get() const;
+
+         /**
+          *  Extract the contained value as if it is of type T. If the
+          *  contained type is not of type T, the value will be converted
+          *  if it can. If no conversion can be found, it will throw.
+          */
+         template< typename T >
+         T get_as();
+
+         template< typename T >
+         const T get_as() const;
+
+
+         // -------------------------------------------------------------------------------
+         //    conversion
+         // -------------------------------------------------------------------------------
+
+         operator string_t() const;
+
+         // -------------------------------------------------------------------------------
+         // -------------------------------------------------------------------------------
+
+
+         base_type::variant_type       & get_ast()       { return base_type::get(); }
+         base_type::variant_type const & get_ast() const { return base_type::get(); }
+   };
+
+
+   /**
+    *  Constructs a value containing an array type
+    */
+   value array();
+
+   /**
+    *  Constructs a value containing an object type
+    */
+   value object();
+
+   bool operator==(value const & a, value const & b);
+   bool operator!=(value const & a, value const & b);
+   bool operator<(value const & a, value const & b);
+
+}}
+
+#include "detail/value_impl.hpp"
+
+
+#endif  // CIERE_JSON_VALUE_HPP