$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81004 - in trunk/libs/spirit/example/qi/json: . build detail json json/detail json/parser parser src test
From: joel_at_[hidden]
Date: 2012-10-17 01:07:57
Author: djowel
Date: 2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
New Revision: 81004
URL: http://svn.boost.org/trac/boost/changeset/81004
Log:
readding proper file structure
Added:
   trunk/libs/spirit/example/qi/json/build/
   trunk/libs/spirit/example/qi/json/build/Jamfile   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/
   trunk/libs/spirit/example/qi/json/json/detail/
   trunk/libs/spirit/example/qi/json/json/detail/io_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/detail/util_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/detail/value_impl.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/io.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/parser/
   trunk/libs/spirit/example/qi/json/json/parser/grammar.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/parser/grammar_def.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/util.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/json/value.hpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/src/
   trunk/libs/spirit/example/qi/json/src/io.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/src/value.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/   (props changed)
   trunk/libs/spirit/example/qi/json/test/Jamfile   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/get.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/get_as.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/test.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/value_array.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/value_basic.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/value_construct.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/value_non_container.cpp   (contents, props changed)
   trunk/libs/spirit/example/qi/json/test/value_object.cpp   (contents, props changed)
Removed:
   trunk/libs/spirit/example/qi/json/detail/
   trunk/libs/spirit/example/qi/json/io.hpp
   trunk/libs/spirit/example/qi/json/parser/
   trunk/libs/spirit/example/qi/json/test.cpp
   trunk/libs/spirit/example/qi/json/util.hpp
   trunk/libs/spirit/example/qi/json/value.hpp
Properties modified: 
   trunk/libs/spirit/example/qi/json/   (props changed)
Added: trunk/libs/spirit/example/qi/json/build/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/build/Jamfile	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,33 @@
+#
+#   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)
+#
+
+import os ;
+local BOOST_ROOT = [ os.environ BOOST_ROOT ] ;
+
+if $(BOOST_ROOT)
+{
+   use-project /boost : $(BOOST_ROOT) ;
+}
+
+project /ciere/json
+        : source-location ../src
+        : requirements <toolset>gcc:<cxxflags>-ftemplate-depth-300
+        : usage-requirements <include>..
+        : default-build <threading>multi
+        : build-dir ../lib
+        ;
+
+
+lib json
+   : [ glob ../src/*.cpp ]
+          /boost//headers
+        :
+   :
+   : <include>..
+        ;
+
Deleted: trunk/libs/spirit/example/qi/json/io.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/json/io.hpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
+++ (empty file)
@@ -1,45 +0,0 @@
-/**
- *   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/json/detail/io_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/detail/io_impl.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/detail/util_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/detail/util_impl.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/detail/value_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/detail/value_impl.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/io.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/io.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/parser/grammar.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/parser/grammar.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/parser/grammar_def.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/parser/grammar_def.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/util.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/util.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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/json/value.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/json/value.hpp	2012-10-17 01:07:54 EDT (Wed, 17 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
Added: trunk/libs/spirit/example/qi/json/src/io.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/src/io.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,17 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *
+ *   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)
+ *
+ */
+
+#include <string>
+#include "../json/value.hpp"
+#include "../json/parser/grammar_def.hpp"
+#include <boost/spirit/include/support_istream_iterator.hpp>
+
+typedef std::string::const_iterator string_iter_t;
+
+template struct ciere::json::parser::grammar<string_iter_t>;
+template struct ciere::json::parser::grammar<boost::spirit::istream_iterator>;
Added: trunk/libs/spirit/example/qi/json/src/value.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/src/value.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,438 @@
+/**
+ *   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)
+ *
+ *
+ */
+
+#include "../json/value.hpp"
+#include <boost/variant.hpp>
+
+namespace ciere { namespace json
+{
+   namespace detail
+   {
+      struct value_compare
+      {
+         typedef bool result_type;
+
+         template <typename A, typename B>
+         bool operator()(A const& a, B const& b) const
+         {
+            return false;
+         }
+
+         template <typename T>
+         bool operator()(T const& a, T const& b) const
+         {
+            return a < b;
+         }
+
+         bool operator()(double_t const& a, int_t const& b) const
+         {
+            return a < b;
+         }
+
+         bool operator()(int_t const& a, double_t const& b) const
+         {
+            return a < b;
+         }
+
+         bool operator()(object_t const& a, object_t const& b)
+         {
+            return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
+         }
+
+         bool operator()(array_t const& a, array_t const& b)
+         {
+            return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
+         }
+      };
+
+
+      struct value_equal
+      {
+         typedef bool result_type;
+
+         template <typename A, typename B>
+         bool operator()(A const& a, B const& b) const
+         {
+            return false;
+         }
+
+         template <typename T>
+         bool operator()(T const& a, T const& b) const
+         {
+            return a == b;
+         }
+
+         bool operator()(double_t const& a, int_t const& b) const
+         {
+            return a == b;
+         }
+
+         bool operator()(int_t const& a, double_t const& b) const
+         {
+            return a == b;
+         }
+
+         bool operator()(object_t const& a, object_t const& b)
+         {
+            if(a.size() != b.size()) { return false; }
+
+            object_t::const_iterator ii = b.begin();
+            for( object_t::const_iterator i = a.begin(); i != a.end(); ++i )
+            {
+               if (*i != *ii++){ return false; }
+            }
+            return true;
+         }
+
+         bool operator()(array_t const& a, array_t const& b)
+         {
+            if(a.size() != b.size()) { return false; }
+
+            array_t::const_iterator ii = b.begin();
+            for( array_t::const_iterator i = a.begin(); i != a.end(); ++i )
+            {
+               if(*i != *ii++) { return false; }
+            }
+            return true;
+         }
+      };
+
+
+      struct get_type : public boost::static_visitor<value_types>
+      {
+         value_types operator()(string_t) const { return string_type; }
+         value_types operator()(int_t)    const { return int_type;    }
+         value_types operator()(double_t) const { return double_type; }
+         value_types operator()(bool_t)   const { return bool_type;   }
+         value_types operator()(null_t)   const { return null_type;   }
+         value_types operator()(object_t) const { return object_type; }
+         value_types operator()(array_t)  const { return array_type;  }
+      };
+
+
+
+      struct get_length : public boost::static_visitor<std::size_t>
+      {
+         std::size_t operator()(const object_t& v) const { return v.size() ; }
+         std::size_t operator()(const array_t& v)  const { return v.size() ; }
+
+         template< typename T >
+         std::size_t operator()(const T&) const { boost::throw_exception( (not_container_type()) ); }
+      };
+
+
+      struct has_key_visitor : public boost::static_visitor<bool>
+      {
+         has_key_visitor(const object_t::key_type & key) : key_(key)  {}
+
+         template< typename T >
+         bool operator()(const T&)             const { return false; }
+
+         bool operator()(const object_t & v)   const { return v.find(key_) != v.end(); }
+
+         const object_t::key_type & key_;
+      };
+
+
+   }  // namespace detail
+
+
+   value_types value::type() const
+   {
+      return boost::apply_visitor(detail::get_type(),*this);
+   }
+
+   std::size_t value::length() const
+   {
+      return boost::apply_visitor(detail::get_length(),*this);
+   }
+
+   // -------------------------------------------------------------------------------
+   //    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.
+    */
+   value::object_iterator value::begin_object()
+   {
+      object_t* p_object = boost::get<object_t>(&base_type::get());
+      if( !p_object ){  boost::throw_exception( (not_object_type()) );  }
+      return object_iterator(p_object->begin(),value::make_json_member());
+   }
+
+   value::const_object_iterator value::begin_object() const
+   {
+      const object_t* p_object = boost::get<object_t>(&base_type::get());
+      if( !p_object ){  boost::throw_exception( (not_object_type()) );  }
+      return const_object_iterator(p_object->begin(),value::make_json_member());
+   }
+
+   /**
+    *  Returns an iterator that can be compared to determine the end of members in an object. If
+    *  the value object_type is in an object then throw not_object_type.
+    */
+   value::object_iterator value::end_object()
+   {
+      object_t* p_object = boost::get<object_t>(&base_type::get());
+      if( !p_object ){  boost::throw_exception( not_object_type() );  }
+      return object_iterator(p_object->end(),value::make_json_member());
+   }
+
+   value::const_object_iterator value::end_object() const
+   {
+      const object_t* p_object = boost::get<object_t>(&base_type::get());
+      if( !p_object ){  boost::throw_exception( not_object_type() );  }
+      return const_object_iterator(p_object->end(),value::make_json_member());
+   }
+
+   /**
+    *  Returns an iterator pointing to the fist member in the array if the value type
+    *  is array_type. Otherwise, throw not_array_type.
+    */
+   value::array_iterator value::begin_array()
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+      if( !p_array ){  boost::throw_exception( not_array_type() );   }
+      return array_iterator(p_array->begin(),value::make_json_value());
+   }
+
+   value::const_array_iterator value::begin_array() const
+   {
+      const array_t* p_array = boost::get<array_t>(&base_type::get());
+      if( !p_array ){  boost::throw_exception( not_array_type() );   }
+      return const_array_iterator(p_array->begin(),value::make_json_value());
+   }
+
+   /**
+    *  Returns an iterator that can be compared to determine the end of the array. If
+    *  the value type is in an array_type then throw not_array_type.
+    */
+   value::array_iterator value::end_array()
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+      if( !p_array ){  boost::throw_exception( not_array_type() );   }
+      return array_iterator(p_array->end(),value::make_json_value());
+   }
+
+   value::const_array_iterator value::end_array() const
+   {
+      const array_t* p_array = boost::get<array_t>(&base_type::get());
+      if( !p_array ){  boost::throw_exception( not_array_type() );   }
+      return const_array_iterator(p_array->end(),value::make_json_value());
+   }
+
+   // -------------------------------------------------------------------------------
+   // -------------------------------------------------------------------------------
+
+
+   // -------------------------------------------------------------------------------
+   //    array handling
+   // -------------------------------------------------------------------------------
+
+
+   value& value::add( const char* v )
+   {
+      return add( string_t(v) );
+   }
+
+
+   value& value::push_back( const char* v )
+   {
+      return push_back( string_t(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& value::at( size_t index )
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+
+      // if this isn't an array type ... throw bad type instead of the out_of_range
+      if( !p_array ){  boost::throw_exception( not_array_type() );  }
+            
+      // container's at method will throw out_of_range if the index is out of range
+      return p_array->at(index);
+   }
+
+
+   const value& value::at( size_t index ) const
+   {
+      const array_t* p_array = boost::get<array_t>(&base_type::get());
+
+      // if this isn't an array type ... throw bad type instead of the out_of_range
+      if( !p_array ){  boost::throw_exception( not_array_type() );  }
+            
+      // container's at method will throw out_of_range if the index is out of range
+      return p_array->at(index);
+   }
+
+
+   /**
+    *  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& value::operator[](int index)
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+      
+      // if this isn't an array type ... it needs to be
+      if( !p_array )
+      {
+         base_type::get() = array_t();
+         p_array = boost::get<array_t>(&base_type::get());
+      }
+
+      // make sure that we are sized appropriately for the index being requested
+      if( p_array->size() < std::size_t(index+1) )
+      {
+         p_array->resize(index+1,null_t());
+      }
+            
+      return (*p_array)[index];
+   }
+
+   const value& value::operator[](int index) const
+   {
+      const array_t* p_array = boost::get<array_t>(&base_type::get());
+
+      // if this isn't an array type or if the index is out of range  ... we can't fix it (const)
+      if( !p_array )                              {  boost::throw_exception( not_array_type() );  }
+      if( p_array->size() < std::size_t(index+1) ){  throw std::out_of_range("json::value array index");         }
+            
+      return (*p_array)[index];
+   }
+
+   value& value::erase(int index)
+   {
+      array_t* p_array = boost::get<array_t>(&base_type::get());
+
+      // if this isn't an array type or if the index is out of range then throw
+      if( !p_array )                              {  boost::throw_exception( not_array_type() );  }
+      if( p_array->size() < std::size_t(index+1) ){  throw std::out_of_range("json::value array index");         }
+      p_array->erase( p_array->begin() + index );
+            
+      return *this;
+   }
+
+   // -------------------------------------------------------------------------------
+   // -------------------------------------------------------------------------------
+
+
+   // -------------------------------------------------------------------------------
+   //    object handling
+   // -------------------------------------------------------------------------------
+
+   value& value::set( string_t const & name, const char* v )
+   {
+      return set( name, string_t(v) );
+   }
+
+   bool value::has_key(const std::string & key) const
+   {
+      object_t::key_type key_(key);
+      return boost::apply_visitor(detail::has_key_visitor(key_),*this);
+   }
+
+   value& value::operator[]( const char* v )
+   {
+      return (*this)[string_t(v)];
+   }
+      
+   value& value::operator[]( const string_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());
+      }
+
+      return (*p_object)[v];
+   }  
+
+
+   const value& value::operator[]( const char* v ) const
+   {
+      return (*this)[string_t(v)];
+   }
+
+
+   const value& value::operator[]( const string_t& v ) const
+   {
+      const object_t* p_object = boost::get<object_t>(&base_type::get());
+
+      if( !p_object ){  boost::throw_exception( not_object_type() );  }
+
+      object_t::const_iterator iter = p_object->find(v);
+
+      // if we don't have a member with the requested name we throw because it is const
+      if( iter == p_object->end() ){  throw std::out_of_range("json::value object member name");  }
+
+      return iter->second;
+   }  
+
+   value& value::erase(string_t const & v)
+   {
+      object_t* p_object = boost::get<object_t>(&base_type::get());
+
+      if( !p_object ){  boost::throw_exception( (not_object_type()) );  }
+
+      p_object->erase(v);
+
+      return *this;
+   }
+
+   // -------------------------------------------------------------------------------
+   // -------------------------------------------------------------------------------
+
+
+
+   // ----------------------------------------------------------------
+   // comparisons
+   // ----------------------------------------------------------------
+
+   bool operator==(value const& a, value const& b)
+   {
+      return boost::apply_visitor(detail::value_equal(), a.get_ast(), b.get_ast());
+   }
+
+   bool operator!=(value const& a, value const& b)
+   {
+      return !(a == b);
+   }
+
+   bool operator<(value const& a, value const& b)
+   {
+      return boost::apply_visitor(detail::value_compare(), a.get_ast(), b.get_ast());
+   }
+
+   // ----------------------------------------------------------------
+   // ----------------------------------------------------------------
+
+
+   value::operator string_t() const
+   {
+      return boost::get<string_t>(base_type::get());
+   }
+
+
+   value array() { return array_t();  }
+   value object(){ return object_t(); }
+
+}}  // namespace ciere::json
+
Deleted: trunk/libs/spirit/example/qi/json/test.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/json/test.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
+++ (empty file)
@@ -1,78 +0,0 @@
-/**
- *   Copyright (C) 2012 ciere consulting, ciere.com
- *   Copyright (C) 2010, 2011 Object Modeling Designs
- */
-
-#include <boost/detail/lightweight_test.hpp>
-#include "value.hpp"
-#include "io.hpp"
-#include "parser/grammar.hpp"
-#include "parser/grammar_def.hpp"
-
-
-int main()
-{
-   boost::spirit::ascii::space_type space;
-
-   {
-      typedef std::string::const_iterator iter_t;
-      typedef ciere::json::parser::grammar<iter_t> grammar_t;
-
-      std::string test_input(
-         "{"
-         "  \"value\"  : 12.34,"
-         "  \"on\"     : false,"
-         "  \"jump\"   : null,"
-         "  \"result\" : [1,34.5,{},\"Sosa did fine.\\u263A\",\"Snowman: \\u2603\"]"
-         "}"
-         );
-
-      grammar_t grammar;
-      ciere::json::value value;
-
-      std::cout << "test input: " << test_input << std::endl;
-
-      iter_t iter = test_input.begin();
-      iter_t end =  test_input.end();
-
-      BOOST_TEST( boost::spirit::qi::phrase_parse( iter, end, grammar, space, value ) );
-      BOOST_TEST( iter == end );
-
-      std::cout << "ast : " << value << std::endl;
-   }
-
-   {
-      typedef std::string::const_iterator iter_t;
-      typedef ciere::json::parser::grammar<iter_t> grammar_t;
-
-      std::string test_input(
-         "{"
-         "  \"foo\":123.456,"
-         "  \"the_value\":        42,"
-         "  \"bar\":[1,\"some test \", {\"on\":false,\"object\":null}],"
-         "  \"gorp\":\"how about this mom\""
-         "}"
-         );
-
-      grammar_t grammar;
-      ciere::json::value value;
-
-      std::cout << "test input: " << test_input << std::endl;
-
-      iter_t iter = test_input.begin();
-      iter_t end =  test_input.end();
-
-      BOOST_TEST( boost::spirit::qi::phrase_parse( iter, end, grammar, space, value ) );
-      BOOST_TEST( iter == end );
-
-      std::cout << "ast : " << value << std::endl;
-      value["bar"].erase(1);
-      std::cout << "ast post erase : " << value << std::endl;
-      value.erase("bar");
-      std::cout << "ast post erase : " << value << std::endl;
-   }
-
-   BOOST_TEST(0);   // show some output
-   return boost::report_errors();
-}
-
Added: trunk/libs/spirit/example/qi/json/test/Jamfile
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/Jamfile	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,60 @@
+#
+#   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)
+#
+import os ;
+import testing ;
+
+project /ciere/json/test
+        : requirements $(TARGET_REQUIREMENTS)
+          <toolset>gcc:<cxxflags>-std=c++0x
+          <toolset>clang:<cxxflags>-std=c++0x
+          <toolset>clang:<cxxflags>-stdlib=libc++
+          <define>BOOST_ALL_NO_LIB=1
+        : default-build <threading>multi
+        : build-dir bin
+        ;
+
+
+{
+	test-suite json_testing :
+
+	[ run test.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run value_basic.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run get.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run get_as.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run value_object.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run value_array.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run value_construct.cpp
+	      ../build//json
+          : : :  : ]
+
+	[ run value_non_container.cpp
+	      ../build//json
+          : : :  : ]
+
+	;
+}
+
+
Added: trunk/libs/spirit/example/qi/json/test/get.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/get.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,76 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+#include <string>
+
+#define SHOULD_HAVE_THROWN 0
+
+namespace json = ciere::json;
+
+int main()
+{
+   json::value value;
+
+   {
+      value = "test";
+      std::string tmp = value.get<json::string_t>();
+      BOOST_TEST(tmp == "test");
+
+      try
+      {
+         value.get<json::int_t>();
+         BOOST_TEST(SHOULD_HAVE_THROWN);
+      }
+      catch(...){}
+   }
+
+
+   {
+      value = 42;
+      int tmp = value.get<json::int_t>();
+      BOOST_TEST(tmp == 42);
+
+      try
+      {
+         value.get<json::float_t>();
+         BOOST_TEST(SHOULD_HAVE_THROWN);
+      }
+      catch(...){}
+   }
+
+
+   {
+      value = 42.3;
+      double tmp = value.get<json::float_t>();
+      BOOST_TEST(tmp == 42.3);
+
+      try
+      {
+         value.get<json::int_t>();
+         BOOST_TEST(SHOULD_HAVE_THROWN);
+      }
+      catch(...){}
+   }
+
+
+
+   {
+      value = false;
+      bool tmp = value.get<json::bool_t>();
+      BOOST_TEST(tmp == false);
+
+      try
+      {
+         value.get<json::int_t>();
+         BOOST_TEST(SHOULD_HAVE_THROWN);
+      }
+      catch(...){}
+   }
+
+
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/get_as.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/get_as.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,79 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+#include <string>
+
+#define SHOULD_HAVE_THROWN 0
+
+namespace json = ciere::json;
+
+int main()
+{
+   json::value value;
+
+   {
+      value = "test";
+      std::string tmp = value.get_as<json::string_t>();
+      BOOST_TEST(tmp == "test");
+   }
+
+
+   {
+      value = 42;
+      int tmp = value.get_as<json::int_t>();
+      BOOST_TEST(tmp == 42);
+      std::string tmp_str = value.get_as<json::string_t>();
+      BOOST_TEST(tmp_str == "42");
+      double tmp_dbl = value.get_as<json::float_t>();
+      BOOST_TEST(tmp_dbl == 42.0);
+   }
+
+
+   {
+      value = 42.5;
+      double tmp = value.get<json::float_t>();
+      BOOST_TEST(tmp == 42.5);
+      std::string tmp_str = value.get_as<json::string_t>();
+      BOOST_TEST(tmp_str == "42.5");
+      int tmp_int = value.get_as<json::int_t>();
+      BOOST_TEST(tmp_int == 42);
+   }
+
+
+   {
+      value = false;
+      bool tmp = value.get_as<json::bool_t>();
+      BOOST_TEST(tmp == false);
+      int tmp_int = value.get_as<int>();
+      BOOST_TEST(tmp_int == 0);
+   }
+
+   {
+      value = "true";
+      BOOST_TEST(true == value.get_as<json::bool_t>());
+   }
+
+   {
+      value = 42;
+      BOOST_TEST(true == value.get_as<json::bool_t>());
+      value = 0;
+      BOOST_TEST(false == value.get_as<json::bool_t>());
+   }
+
+   {
+      value = "42";
+      BOOST_TEST(42 == value.get_as<int>());
+   }
+
+
+   {
+      value = json::null_t();
+   }
+
+
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/test.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,77 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+#include "json/io.hpp"
+#include "json/parser/grammar.hpp"
+#include "json/parser/grammar_def.hpp"
+
+
+int main()
+{
+   boost::spirit::ascii::space_type space;
+
+   {
+      typedef std::string::const_iterator iter_t;
+      typedef ciere::json::parser::grammar<iter_t> grammar_t;
+
+      std::string test_input(
+         "{"
+         "  \"value\"  : 12.34,"
+         "  \"on\"     : false,"
+         "  \"jump\"   : null,"
+         "  \"result\" : [1,34.5,{},\"Sosa did fine.\\u263A\",\"Snowman: \\u2603\"]"
+         "}"
+         );
+
+      grammar_t grammar;
+      ciere::json::value value;
+
+      std::cout << "test input: " << test_input << std::endl;
+
+      iter_t iter = test_input.begin();
+      iter_t end =  test_input.end();
+
+      BOOST_TEST( boost::spirit::qi::phrase_parse( iter, end, grammar, space, value ) );
+      BOOST_TEST( iter == end );
+
+      std::cout << "ast : " << value << std::endl;
+   }
+
+   {
+      typedef std::string::const_iterator iter_t;
+      typedef ciere::json::parser::grammar<iter_t> grammar_t;
+
+      std::string test_input(
+         "{"
+         "  \"foo\":123.456,"
+         "  \"the_value\":        42,"
+         "  \"bar\":[1,\"some test \", {\"on\":false,\"object\":null}],"
+         "  \"gorp\":\"how about this mom\""
+         "}"
+         );
+
+      grammar_t grammar;
+      ciere::json::value value;
+
+      std::cout << "test input: " << test_input << std::endl;
+
+      iter_t iter = test_input.begin();
+      iter_t end =  test_input.end();
+
+      BOOST_TEST( boost::spirit::qi::phrase_parse( iter, end, grammar, space, value ) );
+      BOOST_TEST( iter == end );
+
+      std::cout << "ast : " << value << std::endl;
+      value["bar"].erase(1);
+      std::cout << "ast post erase : " << value << std::endl;
+      value.erase("bar");
+      std::cout << "ast post erase : " << value << std::endl;
+   }
+
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/value_array.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/value_array.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,130 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "json/value.hpp"
+
+namespace json = ciere::json;
+
+void const_test( json::value const & value );
+
+void basic_test()
+{
+   json::value v = json::array()(34)("foo")("bar")(1234.5);
+   BOOST_TEST(v.type() == json::array_type);
+   BOOST_TEST(v.length() == 4);
+   BOOST_TEST(v[1] == "foo");
+   v[1] = "gorp";
+   BOOST_TEST(v[1] == "gorp");
+   BOOST_TEST(v.at(1) == "gorp");
+   v.at(1) = "bar";
+   BOOST_TEST(v.at(1) == "bar");
+
+   v[8] = json::array()(0)(1)(2);
+   BOOST_TEST(v.length() == 9);
+   BOOST_TEST(v[8].length() == 3);
+   BOOST_TEST(v[8].type() == json::array_type);
+   BOOST_TEST(v[8][1] == 1);
+
+   v[8][1] = true;
+   BOOST_TEST(v[8][1] == true);
+   BOOST_TEST(v[8][1] != false);
+
+   try
+   {
+      v.at(10); // will throw
+      BOOST_TEST("didn't throw" == 0);
+   }
+   catch(std::out_of_range&){}
+   catch(...)
+   {
+      BOOST_TEST("wrong throw" == 0);
+   }
+}
+
+
+void reference_test()
+{
+   json::value v = json::array()
+      (123)("foo")(false)(json::array()
+                          (0)(1)(2)(3)(1234.5))
+      ("bar")("gorp");
+
+   v[4] = v[3];
+
+   BOOST_TEST(v[4].type() == json::array_type);
+   BOOST_TEST(v[4][2] == 2 );
+
+   v[3][2] = "gorp";
+   BOOST_TEST(v[3][2] == "gorp");
+   BOOST_TEST(v[4][2] != "gorp");
+   BOOST_TEST(v[4][2] == 2);
+
+   v[3] = 8;
+   BOOST_TEST(v[4] == json::array()(0)(1)(2)(3)(1234.5) );
+}
+
+
+void iterator_test()
+{
+   json::value v = json::array()(0)(1)(2)(3)(4)(5);
+   json::value::array_iterator iter     = v.begin_array();
+   json::value::array_iterator iter_end = v.end_array();
+   int count = 0;
+   while(iter != iter_end)
+   {
+      BOOST_TEST(*iter == count++);
+      *iter = count;
+      ++iter;
+   }
+   BOOST_TEST(count == 6);
+
+   iter     = v.begin_array();
+   iter_end = v.end_array();
+   count = 1;
+   while(iter != iter_end)
+   {
+      BOOST_TEST(*iter == count++);
+      ++iter;
+   }
+}
+
+void const_test( json::value const & v )
+{
+   json::value::const_array_iterator iter     = v.begin_array();
+   json::value::const_array_iterator iter_end = v.end_array();
+   int count = 0;
+   while(iter != iter_end)
+   {
+      BOOST_TEST(*iter == count++);
+#ifdef COMPILE_ERROR
+      *iter = count;  // should create a compile error
+#endif
+      ++iter;
+   }
+   BOOST_TEST(count == 5);
+}
+
+void const_test()
+{
+   json::value v = json::array()(0)(1)(2)(3)(4);
+   const_test(v);
+}
+
+
+int main()
+{
+   basic_test();
+   reference_test();
+   iterator_test();
+   const_test();
+
+   return boost::report_errors();
+}
+
+
+
+
Added: trunk/libs/spirit/example/qi/json/test/value_basic.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/value_basic.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,42 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+
+int main()
+{
+   ciere::json::value value;
+
+   value = "test";
+   BOOST_TEST(value == "test");
+
+   value = 42;
+   BOOST_TEST(value == 42);
+
+   value = 42.3;
+   BOOST_TEST(value == 42.3);
+
+   value = false;
+   BOOST_TEST(value == false);
+
+   value = ciere::json::null_t();
+   BOOST_TEST(value == ciere::json::null_t());
+
+   value = ciere::json::array()(123)("foo")("bar")(42.5);
+   BOOST_TEST(value[1] == "foo");
+   BOOST_TEST(value[3] == 42.5);
+
+   value = ciere::json::object()
+      ("number" ,123)
+      ("foo"    ,"bar")
+      ("meaning", 42);
+   BOOST_TEST(value["number"]  == 123);
+   BOOST_TEST(value["foo"]     == "bar");
+   BOOST_TEST(value["meaning"] == 42);
+
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/value_construct.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/value_construct.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,35 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+#include "json/io.hpp"
+#include "json/parser/grammar_def.hpp"
+
+namespace json = ciere::json;
+
+int main()
+{
+   json::value value;
+
+   BOOST_TEST( value.type() == json::null_type );
+
+   value = json::construct(
+      "{"
+      "   \"foo\"  : 42    ,"
+      "   \"bar\"  : 498.5 ,"
+      "   \"gorp\" : \"ciere\","
+      "   \"bork\" : [\"ciere\",23,false]"
+      "}"
+      );
+
+   BOOST_TEST( value["foo"]  == 42 );
+   BOOST_TEST( value["bar"]  == 498.5 );
+   BOOST_TEST( value["gorp"] == "ciere" );
+   BOOST_TEST( value["bork"][2] == false );
+
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/value_non_container.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/value_non_container.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,232 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ */
+
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+
+namespace json = ciere::json;
+
+void null_test()
+{
+   // default constructs to null
+   json::value v1;
+   json::value v2;
+   BOOST_TEST(v1 == v2);
+   BOOST_TEST(v1.type() == json::null_type);
+   BOOST_TEST(v1 == json::null_t());
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+void bool_test()
+{
+   json::value v1(true);
+   BOOST_TEST(v1.type() == json::bool_type);
+
+   json::value v2(false);
+   BOOST_TEST(v1.type() == json::bool_type);
+
+   BOOST_TEST(v1 != v2);
+   BOOST_TEST(v1 == true);
+   BOOST_TEST(v2 == false);
+
+   v1 = false;
+   BOOST_TEST(v1 == v2);
+
+   v1 = true;
+   BOOST_TEST(v1 != false);
+
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+void string_test()
+{
+   json::value v1("test");
+   BOOST_TEST(v1.type() == json::string_type);
+   BOOST_TEST(v1 == "test");
+
+   std::string s1("foo");
+   json::value v2(s1);
+   BOOST_TEST(v2 == s1);
+
+   v1 = s1;
+   BOOST_TEST(v1 == v2);
+
+   v1 = "foo";
+   BOOST_TEST(v1 == v2);
+
+   v2 = "gorp";
+   BOOST_TEST(v1 != v2);
+   BOOST_TEST(v1 != std::string("bar"));
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+void int_test()
+{
+   json::value v1(12);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == 12);
+
+   v1 = uint8_t(8);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == 8);
+
+   v1 = int8_t(-10);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == -10);
+
+   v1 = uint16_t(923);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == 923);
+
+   v1 = int16_t(-234);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == -234);
+
+   v1 = uint32_t(98);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == 98);
+
+   v1 = int32_t(-8);
+   BOOST_TEST(v1.type() == json::int_type);
+   BOOST_TEST(v1 == -8);
+
+   json::value v2(-8);
+   BOOST_TEST(v1 == v2);
+   BOOST_TEST(v1 == -8.0);
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+void float_test()
+{
+   json::value v1(1.0);
+   BOOST_TEST(v1.type() == json::double_type);
+   BOOST_TEST(v1 == 1.0);
+
+   v1 = 987.5;
+   BOOST_TEST(v1 == 987.5);
+   BOOST_TEST(v1 != 987.1);
+
+   json::value v2(987.5);
+   BOOST_TEST(v1 == v2);
+
+   double d1 = 4.56342124;
+   json::value v3(d1);
+   BOOST_TEST(v3.type() == json::double_type);
+   BOOST_TEST(v3 == d1);
+   BOOST_TEST(v3 != v1);
+
+   v1 = d1;
+   BOOST_TEST(v1 == v3);
+
+   float f1 = 123.4567;
+   json::value v4(f1);
+   BOOST_TEST(v4.type() == json::double_type);
+   BOOST_TEST(v4 == f1);
+   BOOST_TEST(v4 != v1);
+   v1 = f1;
+   BOOST_TEST(v1 == v4);
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+
+void value_test()
+{
+   json::value v1(1234);
+   json::value v2(v1);
+   BOOST_TEST(v2.type() == json::int_type);
+   BOOST_TEST(v2 == 1234);
+
+   // should throw with not a container
+   try
+   {
+      v1.length();
+      BOOST_TEST( "throw fail" == 0 );
+   }
+   catch( json::not_container_type & )
+   {}
+   catch(...)
+   {
+      BOOST_TEST( "throw wrong type" == 0 );
+   }
+}
+
+
+
+
+int main()
+{
+   null_test();
+   bool_test();
+   int_test();
+   float_test();
+   value_test();
+   return boost::report_errors();
+}
+
Added: trunk/libs/spirit/example/qi/json/test/value_object.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/json/test/value_object.cpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
@@ -0,0 +1,95 @@
+/**
+ *   Copyright (C) 2012 ciere consulting, ciere.com
+ *   Copyright (C) 2010, 2011 Object Modeling Designs
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "json/value.hpp"
+#include "json/io.hpp"
+
+namespace json = ciere::json;
+
+void const_test( json::value const & value );
+
+int main()
+{
+   json::value value;
+
+   BOOST_TEST( value.type() == json::null_type );
+
+   value = ciere::json::object()
+      ("number" ,123)
+      ("foo"    ,"bar")
+      ("meaning", 42)
+      ;
+
+   BOOST_TEST( value.type() == json::object_type );
+
+
+   BOOST_TEST(value["number"]  == 123);
+   BOOST_TEST(value["foo"]     == "bar");
+   BOOST_TEST(value["meaning"] == 42);
+
+   value["number"] = 78.3;
+   BOOST_TEST(value["number"]  == 78.3);
+
+   value["foo"] = ciere::json::object()
+      ( "color",  "black" )
+      ( "size" ,  93      )
+      ( "tone" ,  ciere::json::null_t() )
+      ;
+
+   BOOST_TEST(value["foo"]["size"] == 93);
+   BOOST_TEST(value["foo"]["color"] == "black");
+
+   value["foo"]["color"] = "blue";
+   BOOST_TEST(value["foo"]["color"] != "black");
+   BOOST_TEST(value["foo"]["color"] == "blue");
+
+   BOOST_TEST(value["foo"].length() == 3);
+
+   json::value::object_iterator iter     = value["foo"].begin_object();
+   json::value::object_iterator iter_end = value["foo"].end_object();
+   BOOST_TEST( iter->name()  == "color" );
+   BOOST_TEST( iter->value() == "blue" );
+   ++iter;
+   BOOST_TEST( iter->name()  == "size" );
+   BOOST_TEST( iter->value() == 93 );
+   ++iter;
+   BOOST_TEST( iter->name()  == "tone" );
+   BOOST_TEST( iter->value() == json::null_t() );
+   ++iter;
+   BOOST_TEST( iter == iter_end );
+
+   value.set("bar", json::array()(42)("top")(1234.5) );
+   BOOST_TEST( value.has_key("bar") );
+   BOOST_TEST( !value.has_key("cafe") );
+   BOOST_TEST( value["bar"][2] == 1234.5 );
+
+   value.set("cafe", "open");
+   BOOST_TEST(value["cafe"] == "open" );
+
+   const_test(value);
+
+   return boost::report_errors();
+}
+
+
+
+void const_test( json::value const & value )
+{
+   BOOST_TEST( value.has_key("cafe") );
+
+   try
+   {
+      value["sam"];
+      int should_have_thrown = 1;
+      BOOST_TEST( should_have_thrown == 0 );
+   }
+   catch( std::out_of_range & e )
+   {}
+
+   BOOST_TEST( value["cafe"] == "open" );
+   BOOST_TEST( value["bar"][2] == 1234.5 );
+}
+
Deleted: trunk/libs/spirit/example/qi/json/util.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/json/util.hpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
+++ (empty file)
@@ -1,32 +0,0 @@
-/**
- *   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
Deleted: trunk/libs/spirit/example/qi/json/value.hpp
==============================================================================
--- trunk/libs/spirit/example/qi/json/value.hpp	2012-10-17 01:07:54 EDT (Wed, 17 Oct 2012)
+++ (empty file)
@@ -1,390 +0,0 @@
-/**
- *   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