$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r67437 - in trunk: boost/spirit/home/karma boost/spirit/home/karma/detail boost/spirit/home/karma/directive boost/spirit/home/qi boost/spirit/home/qi/directive boost/spirit/home/support boost/spirit/home/support/utree boost/spirit/include libs/spirit/test/karma libs/spirit/test/qi libs/spirit/test/support
From: admin_at_[hidden]
Date: 2010-12-23 16:14:52
Author: wash
Date: 2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
New Revision: 67437
URL: http://svn.boost.org/trac/boost/changeset/67437
Log:
Added the as directive.
Added:
   trunk/boost/spirit/home/karma/detail/as.hpp
      - copied, changed from r67430, /trunk/boost/spirit/home/karma/detail/as_string.hpp
   trunk/boost/spirit/home/karma/directive/as.hpp
      - copied, changed from r67430, /trunk/boost/spirit/home/karma/directive/as_string.hpp
   trunk/boost/spirit/home/qi/directive/as.hpp
      - copied, changed from r67430, /trunk/boost/spirit/home/qi/directive/as_string.hpp
   trunk/boost/spirit/include/karma_as.hpp
      - copied, changed from r67430, /trunk/boost/spirit/include/karma_as_string.hpp
   trunk/boost/spirit/include/qi_as.hpp
      - copied, changed from r67430, /trunk/boost/spirit/include/qi_as_string.hpp
Removed:
   trunk/boost/spirit/home/karma/detail/as_string.hpp
   trunk/boost/spirit/home/karma/directive/as_string.hpp
   trunk/boost/spirit/home/qi/directive/as_string.hpp
   trunk/boost/spirit/include/karma_as_string.hpp
   trunk/boost/spirit/include/qi_as_string.hpp
Text files modified: 
   trunk/boost/spirit/home/karma/detail/as.hpp            |    47 +++++++++++++-----                      
   trunk/boost/spirit/home/karma/directive.hpp            |     2                                         
   trunk/boost/spirit/home/karma/directive/as.hpp         |    72 +++++++++++++++++++--------             
   trunk/boost/spirit/home/qi/directive.hpp               |     2                                         
   trunk/boost/spirit/home/qi/directive/as.hpp            |    67 +++++++++++++++++++-------              
   trunk/boost/spirit/home/support/attributes_fwd.hpp     |    18 ++++--                                  
   trunk/boost/spirit/home/support/common_terminals.hpp   |     1                                         
   trunk/boost/spirit/home/support/utree/utree_traits.hpp |   101 ++++++++++++++++++++++++++++++++++++++- 
   trunk/boost/spirit/include/karma_as.hpp                |     7 +-                                      
   trunk/boost/spirit/include/qi_as.hpp                   |     7 +-                                      
   trunk/libs/spirit/test/karma/utree.cpp                 |    38 ++++++++++++++                          
   trunk/libs/spirit/test/qi/utree.cpp                    |    77 +++++++++++++++++++++++++++--           
   trunk/libs/spirit/test/support/utree_test.cpp          |    52 +++++++++++++++++++                     
   13 files changed, 409 insertions(+), 82 deletions(-)
Copied: trunk/boost/spirit/home/karma/detail/as.hpp (from r67430, /trunk/boost/spirit/home/karma/detail/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/karma/detail/as_string.hpp	(original)
+++ trunk/boost/spirit/home/karma/detail/as.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -23,8 +23,8 @@
     ///////////////////////////////////////////////////////////////////////////
 
     // This is the default case: the plain attribute values
-    template <typename Attribute, typename Enable/*= void*/>
-    struct attribute_as_string
+    template <typename T, typename Attribute, typename Enable/*= void*/>
+    struct attribute_as_xxx
     {
         typedef Attribute const& type; 
 
@@ -32,38 +32,57 @@
         {
             return attr;
         }
+
+        static bool is_valid(Attribute const& attr)
+        {
+            return true;
+        }
     };
 
     ///////////////////////////////////////////////////////////////////////////
-    template <typename Attribute>
-    typename spirit::result_of::attribute_as_string<Attribute>::type
-    as_string(Attribute const& attr)
+    template <typename T, typename Attribute>
+    inline typename spirit::result_of::attribute_as_xxx<T, Attribute>::type
+    as(Attribute const& attr)
     {
-        return attribute_as_string<Attribute>::call(attr);
+        return attribute_as_xxx<T, Attribute>::call(attr);
     }
 
-    inline unused_type as_string(unused_type)
+    template <typename T>
+    inline unused_type as(unused_type)
     {
         return unused;
     }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Attribute>
+    inline bool valid_as(Attribute const& attr)
+    {
+        return attribute_as_xxx<T, Attribute>::is_valid(attr);
+    }
+
+    template <typename T>
+    inline bool valid_as(unused_type)
+    {
+        return true;
+    }
 }}}
 
 ///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace result_of
 {
-    template <typename Attribute>
-    struct attribute_as_string
-      : traits::attribute_as_string<Attribute>
+    template <typename T, typename Attribute>
+    struct attribute_as_xxx
+      : traits::attribute_as_xxx<T, Attribute>
     {};
 
-    template <>
-    struct attribute_as_string<unused_type>
+    template <typename T>
+    struct attribute_as_xxx<T, unused_type>
     {
         typedef unused_type type;
     };
 
-    template <>
-    struct attribute_as_string<unused_type const>
+    template <typename T>
+    struct attribute_as_xxx<T, unused_type const>
     {
         typedef unused_type type;
     };
Deleted: trunk/boost/spirit/home/karma/detail/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/as_string.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,72 +0,0 @@
-//  Copyright (c) 2001-2010 Hartmut Kaiser
-//
-//  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)
-
-#if !defined(BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM)
-#define BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/attributes_fwd.hpp>
-
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace traits
-{
-    ///////////////////////////////////////////////////////////////////////////
-    //  This file contains the attribute to string conversion utility. The 
-    //  utility provided also accept spirit's unused_type; all no-ops. Compiler 
-    //  optimization will easily strip these away.
-    ///////////////////////////////////////////////////////////////////////////
-
-    // This is the default case: the plain attribute values
-    template <typename Attribute, typename Enable/*= void*/>
-    struct attribute_as_string
-    {
-        typedef Attribute const& type; 
-
-        static type call(Attribute const& attr)
-        {
-            return attr;
-        }
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Attribute>
-    typename spirit::result_of::attribute_as_string<Attribute>::type
-    as_string(Attribute const& attr)
-    {
-        return attribute_as_string<Attribute>::call(attr);
-    }
-
-    inline unused_type as_string(unused_type)
-    {
-        return unused;
-    }
-}}}
-
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace result_of
-{
-    template <typename Attribute>
-    struct attribute_as_string
-      : traits::attribute_as_string<Attribute>
-    {};
-
-    template <>
-    struct attribute_as_string<unused_type>
-    {
-        typedef unused_type type;
-    };
-
-    template <>
-    struct attribute_as_string<unused_type const>
-    {
-        typedef unused_type type;
-    };
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/karma/directive.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive.hpp	(original)
+++ trunk/boost/spirit/home/karma/directive.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -70,6 +70,6 @@
 //  as_string and as_wstring directives
 //  as_string[...], as_wstring[...]
 ///////////////////////////////////////////////////////////////////////////////
-#include <boost/spirit/home/karma/directive/as_string.hpp>
+#include <boost/spirit/home/karma/directive/as.hpp>
 
 #endif
Copied: trunk/boost/spirit/home/karma/directive/as.hpp (from r67430, /trunk/boost/spirit/home/karma/directive/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/karma/directive/as_string.hpp	(original)
+++ trunk/boost/spirit/home/karma/directive/as.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,10 +1,11 @@
 //  Copyright (c) 2001-2010 Hartmut Kaiser
+//  Copyright (c)      2010 Bryce Lelbach
 //
 //  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)
 
-#if !defined(SPIRIT_KARMA_AS_STRING_DEC_18_0510PM)
-#define SPIRIT_KARMA_AS_STRING_DEC_18_0510PM
+#if !defined(SPIRIT_KARMA_AS_DEC_18_0510PM)
+#define SPIRIT_KARMA_AS_DEC_18_0510PM
 
 #if defined(_MSC_VER)
 #pragma once
@@ -14,7 +15,7 @@
 #include <boost/spirit/home/karma/generator.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
-#include <boost/spirit/home/karma/detail/as_string.hpp>
+#include <boost/spirit/home/karma/detail/as.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
@@ -22,18 +23,34 @@
 #include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
+namespace boost { namespace spirit { namespace karma
+{
+    template <typename T>
+    struct as
+      : stateful_tag_type<T, tag::as>
+    {};
+}}}
+
 namespace boost { namespace spirit
 {
     ///////////////////////////////////////////////////////////////////////////
     // Enablers
     ///////////////////////////////////////////////////////////////////////////
+    // enables as_string[...]
     template <>
-    struct use_directive<karma::domain, tag::as_string> // enables as_string
+    struct use_directive<karma::domain, tag::as_string> 
       : mpl::true_ {};
 
+    // enables as_wstring[...]
     template <>
-    struct use_directive<karma::domain, tag::as_wstring> // enables as_wstring
+    struct use_directive<karma::domain, tag::as_wstring> 
       : mpl::true_ {};
+
+    // enables as<T>[...]
+    template <typename T>
+    struct use_directive<karma::domain, tag::stateful_tag<T, tag::as> > 
+      : mpl::true_ 
+    {};
 }}
 
 namespace boost { namespace spirit { namespace karma
@@ -44,17 +61,17 @@
     using spirit::as_wstring_type;
 
     ///////////////////////////////////////////////////////////////////////////
-    // as_string_directive allows to hook custom conversions to string into the
+    // as_directive allows to hook custom conversions to string into the
     // output generation process
     ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Char>
-    struct as_string_directive 
-      : unary_generator<as_string_directive<Subject, Char> >
+    template <typename Subject, typename T>
+    struct as_directive 
+      : unary_generator<as_directive<Subject, T> >
     {
         typedef Subject subject_type;
         typedef typename subject_type::properties properties;
 
-        as_string_directive(Subject const& subject)
+        as_directive(Subject const& subject)
           : subject(subject) {}
 
         template <typename Context, typename Iterator>
@@ -67,14 +84,17 @@
         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
           , Attribute const& attr) const
         {
-            return subject.generate(sink, ctx, d, traits::as_string(attr)) &&
-                   karma::delimit_out(sink, d);     // always do post-delimiting 
+            if (!traits::valid_as<T>(attr))
+                return false;
+            else 
+                return subject.generate(sink, ctx, d, traits::as<T>(attr)) &&
+                       karma::delimit_out(sink, d); // always do post-delimiting
         }
 
         template <typename Context>
         info what(Context& context) const
         {
-            return info("as_string", subject.what(context));
+            return info("as", subject.what(context));
         }
 
         Subject subject;
@@ -86,8 +106,7 @@
     template <typename Subject, typename Modifiers>
     struct make_directive<tag::as_string, Subject, Modifiers>
     {
-        typedef as_string_directive<Subject, char> result_type;
-
+        typedef as_directive<Subject, std::string> result_type;
         result_type operator()(unused_type, Subject const& subject
           , unused_type) const
         {
@@ -98,8 +117,18 @@
     template <typename Subject, typename Modifiers>
     struct make_directive<tag::as_wstring, Subject, Modifiers>
     {
-        typedef as_string_directive<Subject, wchar_t> result_type;
-
+        typedef as_directive<Subject, std::wstring> result_type;
+        result_type operator()(unused_type, Subject const& subject
+          , unused_type) const
+        {
+            return result_type(subject);
+        }
+    };
+    
+    template <typename T, typename Subject, typename Modifiers>
+    struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
+    {
+        typedef as_directive<Subject, T> result_type;
         result_type operator()(unused_type, Subject const& subject
           , unused_type) const
         {
@@ -111,14 +140,13 @@
 namespace boost { namespace spirit { namespace traits
 {
     ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Char>
-    struct has_semantic_action<karma::as_string_directive<Subject, Char> >
+    template <typename Subject, typename T>
+    struct has_semantic_action<karma::as_directive<Subject, T> >
       : unary_has_semantic_action<Subject> {};
 
     ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Attribute, typename Char>
-    struct handles_container<
-            karma::as_string_directive<Subject, Char>, Attribute>
+    template <typename Subject, typename Attribute, typename T>
+    struct handles_container<karma::as_directive<Subject, T>, Attribute>
       : mpl::false_ {};   // always dereference attribute if used in sequences
 }}}
 
Deleted: trunk/boost/spirit/home/karma/directive/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/as_string.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,125 +0,0 @@
-//  Copyright (c) 2001-2010 Hartmut Kaiser
-//
-//  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)
-
-#if !defined(SPIRIT_KARMA_AS_STRING_DEC_18_0510PM)
-#define SPIRIT_KARMA_AS_STRING_DEC_18_0510PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/karma/meta_compiler.hpp>
-#include <boost/spirit/home/karma/generator.hpp>
-#include <boost/spirit/home/karma/domain.hpp>
-#include <boost/spirit/home/karma/detail/output_iterator.hpp>
-#include <boost/spirit/home/karma/detail/as_string.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/common_terminals.hpp>
-#include <boost/spirit/home/support/has_semantic_action.hpp>
-#include <boost/spirit/home/support/handles_container.hpp>
-#include <boost/spirit/home/karma/detail/attributes.hpp>
-
-namespace boost { namespace spirit
-{
-    ///////////////////////////////////////////////////////////////////////////
-    // Enablers
-    ///////////////////////////////////////////////////////////////////////////
-    template <>
-    struct use_directive<karma::domain, tag::as_string> // enables as_string
-      : mpl::true_ {};
-
-    template <>
-    struct use_directive<karma::domain, tag::as_wstring> // enables as_wstring
-      : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace karma
-{
-    using spirit::as_string;
-    using spirit::as_string_type;
-    using spirit::as_wstring;
-    using spirit::as_wstring_type;
-
-    ///////////////////////////////////////////////////////////////////////////
-    // as_string_directive allows to hook custom conversions to string into the
-    // output generation process
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Char>
-    struct as_string_directive 
-      : unary_generator<as_string_directive<Subject, Char> >
-    {
-        typedef Subject subject_type;
-        typedef typename subject_type::properties properties;
-
-        as_string_directive(Subject const& subject)
-          : subject(subject) {}
-
-        template <typename Context, typename Iterator>
-        struct attribute
-          : traits::attribute_of<subject_type, Context, Iterator>
-        {};
-
-        template <typename OutputIterator, typename Context, typename Delimiter
-          , typename Attribute>
-        bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
-          , Attribute const& attr) const
-        {
-            return subject.generate(sink, ctx, d, traits::as_string(attr)) &&
-                   karma::delimit_out(sink, d);     // always do post-delimiting 
-        }
-
-        template <typename Context>
-        info what(Context& context) const
-        {
-            return info("as_string", subject.what(context));
-        }
-
-        Subject subject;
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Generator generators: make_xxx function (objects)
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Modifiers>
-    struct make_directive<tag::as_string, Subject, Modifiers>
-    {
-        typedef as_string_directive<Subject, char> result_type;
-
-        result_type operator()(unused_type, Subject const& subject
-          , unused_type) const
-        {
-            return result_type(subject);
-        }
-    };
-
-    template <typename Subject, typename Modifiers>
-    struct make_directive<tag::as_wstring, Subject, Modifiers>
-    {
-        typedef as_string_directive<Subject, wchar_t> result_type;
-
-        result_type operator()(unused_type, Subject const& subject
-          , unused_type) const
-        {
-            return result_type(subject);
-        }
-    };
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Char>
-    struct has_semantic_action<karma::as_string_directive<Subject, Char> >
-      : unary_has_semantic_action<Subject> {};
-
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Attribute, typename Char>
-    struct handles_container<
-            karma::as_string_directive<Subject, Char>, Attribute>
-      : mpl::false_ {};   // always dereference attribute if used in sequences
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/qi/directive.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive.hpp	(original)
+++ trunk/boost/spirit/home/qi/directive.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -11,7 +11,7 @@
 #pragma once
 #endif
 
-#include <boost/spirit/home/qi/directive/as_string.hpp>
+#include <boost/spirit/home/qi/directive/as.hpp>
 #include <boost/spirit/home/qi/directive/encoding.hpp>
 #include <boost/spirit/home/qi/directive/hold.hpp>
 #include <boost/spirit/home/qi/directive/lexeme.hpp>
Copied: trunk/boost/spirit/home/qi/directive/as.hpp (from r67430, /trunk/boost/spirit/home/qi/directive/as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/home/qi/directive/as_string.hpp	(original)
+++ trunk/boost/spirit/home/qi/directive/as.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,11 +1,13 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
+    Copyright (c) 2001-2010 Hartmut Kaiser
+    Copyright (c)      2010 Bryce Lelbach
 
     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)
 =============================================================================*/
-#if !defined(SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM)
-#define SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM
+#if !defined(SPIRIT_AS_DECEMBER_6_2010_1013AM)
+#define SPIRIT_AS_DECEMBER_6_2010_1013AM
 
 #if defined(_MSC_VER)
 #pragma once
@@ -23,18 +25,34 @@
 #include <boost/range/iterator_range.hpp>
 #include <string>
 
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename T>
+    struct as
+      : stateful_tag_type<T, tag::as>
+    {};
+}}}
+
 namespace boost { namespace spirit
 {
     ///////////////////////////////////////////////////////////////////////////
     // Enablers
     ///////////////////////////////////////////////////////////////////////////
+    // enables as_string[...]
     template <>
-    struct use_directive<qi::domain, tag::as_string> // enables as_string
+    struct use_directive<qi::domain, tag::as_string> 
       : mpl::true_ {};
 
+    // enables as_wstring[...]
     template <>
-    struct use_directive<qi::domain, tag::as_wstring> // enables as_wstring
+    struct use_directive<qi::domain, tag::as_wstring> 
       : mpl::true_ {};
+
+    // enables as<T>[...]
+    template <typename T>
+    struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> > 
+      : mpl::true_ 
+    {};
 }}
 
 namespace boost { namespace spirit { namespace qi
@@ -44,17 +62,17 @@
     using spirit::as_wstring;
     using spirit::as_wstring_type;
 
-    template <typename Subject, typename Char>
-    struct as_string_directive : unary_parser<as_string_directive<Subject, Char> >
+    template <typename Subject, typename T>
+    struct as_directive : unary_parser<as_directive<Subject, T> >
     {
         typedef Subject subject_type;
-        as_string_directive(Subject const& subject)
+        as_directive(Subject const& subject)
           : subject(subject) {}
 
         template <typename Context, typename Iterator>
         struct attribute
         {
-            typedef std::basic_string<Char> type;
+            typedef T type;
         };
 
         template <typename Iterator, typename Context
@@ -64,10 +82,10 @@
         {
             qi::skip_over(first, last, skipper);
             Iterator i = first;
-            std::basic_string<Char> str_attr;
-            if (subject.parse(i, last, context, skipper, str_attr))
+            T as_attr;
+            if (subject.parse(i, last, context, skipper, as_attr))
             {
-                spirit::traits::assign_to(str_attr, attr);
+                spirit::traits::assign_to(as_attr, attr);
                 first = i;
                 return true;
             }
@@ -77,7 +95,7 @@
         template <typename Context>
         info what(Context& context) const
         {
-            return info("as_string", subject.what(context));
+            return info("as", subject.what(context));
         }
 
         Subject subject;
@@ -89,8 +107,9 @@
     template <typename Subject, typename Modifiers>
     struct make_directive<tag::as_string, Subject, Modifiers>
     {
-        typedef as_string_directive<Subject, char> result_type;
-        result_type operator()(unused_type, Subject const& subject, unused_type) const
+        typedef as_directive<Subject, std::string> result_type;
+        result_type operator()(unused_type, Subject const& subject
+          , unused_type) const
         {
             return result_type(subject);
         }
@@ -99,8 +118,20 @@
     template <typename Subject, typename Modifiers>
     struct make_directive<tag::as_wstring, Subject, Modifiers>
     {
-        typedef as_string_directive<Subject, wchar_t> result_type;
-        result_type operator()(unused_type, Subject const& subject, unused_type) const
+        typedef as_directive<Subject, std::wstring> result_type;
+        result_type operator()(unused_type, Subject const& subject
+          , unused_type) const
+        {
+            return result_type(subject);
+        }
+    };
+    
+    template <typename T, typename Subject, typename Modifiers>
+    struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
+    {
+        typedef as_directive<Subject, T> result_type;
+        result_type operator()(unused_type, Subject const& subject
+          , unused_type) const
         {
             return result_type(subject);
         }
@@ -109,8 +140,8 @@
 
 namespace boost { namespace spirit { namespace traits
 {
-    template <typename Subject, typename Char>
-    struct has_semantic_action<qi::as_string_directive<Subject, Char> >
+    template <typename Subject, typename T>
+    struct has_semantic_action<qi::as_directive<Subject, T> >
       : unary_has_semantic_action<Subject> {};
 }}}
 
Deleted: trunk/boost/spirit/home/qi/directive/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/as_string.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,117 +0,0 @@
-/*=============================================================================
-    Copyright (c) 2001-2010 Joel de Guzman
-
-    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)
-=============================================================================*/
-#if !defined(SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM)
-#define SPIRIT_AS_STRING_DECEMBER_6_2010_1013AM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/skip_over.hpp>
-#include <boost/spirit/home/qi/parser.hpp>
-#include <boost/spirit/home/qi/detail/assign_to.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/common_terminals.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/spirit/home/support/has_semantic_action.hpp>
-#include <boost/range/iterator_range.hpp>
-#include <string>
-
-namespace boost { namespace spirit
-{
-    ///////////////////////////////////////////////////////////////////////////
-    // Enablers
-    ///////////////////////////////////////////////////////////////////////////
-    template <>
-    struct use_directive<qi::domain, tag::as_string> // enables as_string
-      : mpl::true_ {};
-
-    template <>
-    struct use_directive<qi::domain, tag::as_wstring> // enables as_wstring
-      : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace qi
-{
-    using spirit::as_string;
-    using spirit::as_string_type;
-    using spirit::as_wstring;
-    using spirit::as_wstring_type;
-
-    template <typename Subject, typename Char>
-    struct as_string_directive : unary_parser<as_string_directive<Subject, Char> >
-    {
-        typedef Subject subject_type;
-        as_string_directive(Subject const& subject)
-          : subject(subject) {}
-
-        template <typename Context, typename Iterator>
-        struct attribute
-        {
-            typedef std::basic_string<Char> type;
-        };
-
-        template <typename Iterator, typename Context
-          , typename Skipper, typename Attribute>
-        bool parse(Iterator& first, Iterator const& last
-          , Context& context, Skipper const& skipper, Attribute& attr) const
-        {
-            qi::skip_over(first, last, skipper);
-            Iterator i = first;
-            std::basic_string<Char> str_attr;
-            if (subject.parse(i, last, context, skipper, str_attr))
-            {
-                spirit::traits::assign_to(str_attr, attr);
-                first = i;
-                return true;
-            }
-            return false;
-        }
-
-        template <typename Context>
-        info what(Context& context) const
-        {
-            return info("as_string", subject.what(context));
-        }
-
-        Subject subject;
-    };
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Parser generators: make_xxx function (objects)
-    ///////////////////////////////////////////////////////////////////////////
-    template <typename Subject, typename Modifiers>
-    struct make_directive<tag::as_string, Subject, Modifiers>
-    {
-        typedef as_string_directive<Subject, char> result_type;
-        result_type operator()(unused_type, Subject const& subject, unused_type) const
-        {
-            return result_type(subject);
-        }
-    };
-
-    template <typename Subject, typename Modifiers>
-    struct make_directive<tag::as_wstring, Subject, Modifiers>
-    {
-        typedef as_string_directive<Subject, wchar_t> result_type;
-        result_type operator()(unused_type, Subject const& subject, unused_type) const
-        {
-            return result_type(subject);
-        }
-    };
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
-    template <typename Subject, typename Char>
-    struct has_semantic_action<qi::as_string_directive<Subject, Char> >
-      : unary_has_semantic_action<Subject> {};
-}}}
-
-#endif
Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,6 +1,7 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Hartmut Kaiser
     Copyright (c) 2001-2010 Joel de Guzman
+    Copyright (c)      2010 Bryce Lelbach
 
     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)
@@ -25,8 +26,8 @@
     template <typename Exposed, typename Attribute>
     struct extract_from;
 
-    template <typename Attribute>
-    struct attribute_as_string;
+    template <typename T, typename Attribute>
+    struct attribute_as_xxx;
 
     template <typename Exposed, typename Transformed, typename Domain>
     struct pre_transform;
@@ -122,12 +123,15 @@
 
     ///////////////////////////////////////////////////////////////////////////
     // Karma only
-    template <typename Attribute, typename Enable = void>
-    struct attribute_as_string;
+    template <typename T, typename Attribute, typename Enable = void>
+    struct attribute_as_xxx;
 
-    template <typename Attribute>
-    typename spirit::result_of::attribute_as_string<Attribute>::type
-    as_string(Attribute const& attr);
+    template <typename T, typename Attribute>
+    typename spirit::result_of::attribute_as_xxx<T, Attribute>::type
+    as(Attribute const& attr);
+    
+    template <typename T, typename Attribute>
+    bool valid_as(Attribute const& attr);
 
     ///////////////////////////////////////////////////////////////////////////
     // return the type currently stored in the given variant
Modified: trunk/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- trunk/boost/spirit/home/support/common_terminals.hpp	(original)
+++ trunk/boost/spirit/home/support/common_terminals.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -140,6 +140,7 @@
     namespace tag
     {
         struct attr_cast {};
+        struct as {};
     }
 
 }}
Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp	(original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -22,6 +22,8 @@
 #include <boost/range/iterator_range.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/identity.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_same.hpp>
 #include <boost/utility/enable_if.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -240,15 +242,108 @@
 
     ///////////////////////////////////////////////////////////////////////////
     // Karma only: convert utree node to string
-    template <>
-    struct attribute_as_string<utree>
-    {
+    template <typename T>
+    struct attribute_as_xxx<T, utree,
+        typename enable_if<mpl::or_<
+            boost::is_same<T, std::string>
+          , boost::is_same<T, utf8_string_type>
+          , boost::is_same<T, utf8_string_range_type>
+        > >::type
+    > {
         typedef utf8_string_range_type type; 
 
         static type call(utree const& attr)
         {
             return boost::get<utf8_string_range_type>(attr);
         }
+        
+        static bool is_valid(utree const& attr)
+        {
+            switch (attr.which())
+            {
+                case utree_type::reference_type:
+                    {
+                        return is_valid(attr.deref());
+                    }
+                case utree_type::string_range_type:
+                case utree_type::string_type:
+                    {
+                        return true;
+                    }
+                default:
+                    {
+                        return false;
+                    }
+            }
+        }
+    };
+    
+    template <typename T>
+    struct attribute_as_xxx<T, utree,
+        typename enable_if<mpl::or_<
+            boost::is_same<T, utf8_symbol_type>
+          , boost::is_same<T, utf8_symbol_range_type>
+        > >::type
+    > {
+        typedef utf8_symbol_range_type type; 
+
+        static type call(utree const& attr)
+        {
+            return boost::get<utf8_symbol_range_type>(attr);
+        }
+        
+        static bool is_valid(utree const& attr)
+        {
+            switch (attr.which())
+            {
+                case utree_type::reference_type:
+                    {
+                        return is_valid(attr.deref());
+                    }
+                case utree_type::symbol_type:
+                    {
+                        return true;
+                    }
+                default:
+                    {
+                        return false;
+                    }
+            }
+        }
+    };
+
+    template <typename T>
+    struct attribute_as_xxx<T, utree,
+        typename enable_if<mpl::or_<
+            boost::is_same<T, binary_string_type>
+          , boost::is_same<T, binary_range_type>
+        > >::type
+    > {
+        typedef binary_range_type type; 
+
+        static type call(utree const& attr)
+        {
+            return boost::get<binary_range_type>(attr);
+        }
+
+        static bool is_valid(utree const& attr)
+        {
+            switch (attr.which())
+            {
+                case utree_type::reference_type:
+                    {
+                        return is_valid(attr.deref());
+                    }
+                case utree_type::binary_type:
+                    {
+                        return true;
+                    }
+                default:
+                    {
+                        return false;
+                    }
+            }
+        }
     };
 
     ///////////////////////////////////////////////////////////////////////////
Copied: trunk/boost/spirit/include/karma_as.hpp (from r67430, /trunk/boost/spirit/include/karma_as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/include/karma_as_string.hpp	(original)
+++ trunk/boost/spirit/include/karma_as.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,18 +1,19 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
     Copyright (c) 2001-2010 Hartmut Kaiser
+    Copyright (c)      2010 Bryce Lelbach
     http://spirit.sourceforge.net/
 
     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 BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
+#ifndef BOOST_SPIRIT_INCLUDE_KARMA_AS
+#define BOOST_SPIRIT_INCLUDE_KARMA_AS
 
 #if defined(_MSC_VER)
 #pragma once
 #endif
 
-#include <boost/spirit/home/karma/directive/as_string.hpp>
+#include <boost/spirit/home/karma/directive/as.hpp>
 
 #endif
Deleted: trunk/boost/spirit/include/karma_as_string.hpp
==============================================================================
--- trunk/boost/spirit/include/karma_as_string.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,18 +0,0 @@
-/*=============================================================================
-    Copyright (c) 2001-2010 Joel de Guzman
-    Copyright (c) 2001-2010 Hartmut Kaiser
-    http://spirit.sourceforge.net/
-
-    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 BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/karma/directive/as_string.hpp>
-
-#endif
Copied: trunk/boost/spirit/include/qi_as.hpp (from r67430, /trunk/boost/spirit/include/qi_as_string.hpp)
==============================================================================
--- /trunk/boost/spirit/include/qi_as_string.hpp	(original)
+++ trunk/boost/spirit/include/qi_as.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,18 +1,19 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
     Copyright (c) 2001-2010 Hartmut Kaiser
+    Copyright (c)      2010 Bryce Lelbach
     http://spirit.sourceforge.net/
 
     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 BOOST_SPIRIT_INCLUDE_QI_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_QI_AS_STRING
+#ifndef BOOST_SPIRIT_INCLUDE_QI_AS
+#define BOOST_SPIRIT_INCLUDE_QI_AS
 
 #if defined(_MSC_VER)
 #pragma once
 #endif
 
-#include <boost/spirit/home/qi/directive/as_string.hpp>
+#include <boost/spirit/home/qi/directive/as.hpp>
 
 #endif
Deleted: trunk/boost/spirit/include/qi_as_string.hpp
==============================================================================
--- trunk/boost/spirit/include/qi_as_string.hpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
+++ (empty file)
@@ -1,18 +0,0 @@
-/*=============================================================================
-    Copyright (c) 2001-2010 Joel de Guzman
-    Copyright (c) 2001-2010 Hartmut Kaiser
-    http://spirit.sourceforge.net/
-
-    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 BOOST_SPIRIT_INCLUDE_QI_AS_STRING
-#define BOOST_SPIRIT_INCLUDE_QI_AS_STRING
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/directive/as_string.hpp>
-
-#endif
Modified: trunk/libs/spirit/test/karma/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/utree.cpp	(original)
+++ trunk/libs/spirit/test/karma/utree.cpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,5 +1,6 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
 // Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c)      2010 Bryce Lelbach
 //
 // 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)
@@ -167,7 +168,8 @@
         BOOST_TEST(test("", -char_, ut));
     }
 
-    {
+    // as_string
+    {   
         using boost::spirit::karma::digit;
         using boost::spirit::karma::as_string;
 
@@ -183,6 +185,40 @@
         BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
     }
     
+    // as
+    {
+        using boost::spirit::karma::digit;
+        using boost::spirit::karma::as;
+        
+        typedef as<std::string> as_string_type;
+        as_string_type const as_string = as_string_type();
+
+        typedef as<utf8_symbol_type> as_symbol_type;
+        as_symbol_type const as_symbol = as_symbol_type();
+
+        utree ut("xy");
+        BOOST_TEST(test("xy", string, ut));
+        BOOST_TEST(test("xy", as_string[*char_], ut));
+        BOOST_TEST(test("x,y", as_string[char_ << ',' << char_], ut));
+
+        ut.clear();
+        ut.push_back("ab");
+        ut.push_back(1.2);
+        BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut));
+        BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
+        
+        ut = utf8_symbol_type("xy");
+        BOOST_TEST(test("xy", string, ut));
+        BOOST_TEST(test("xy", as_symbol[*char_], ut));
+        BOOST_TEST(test("x,y", as_symbol[char_ << ',' << char_], ut));
+
+        ut.clear();
+        ut.push_back(utf8_symbol_type("ab"));
+        ut.push_back(1.2);
+        BOOST_TEST(test("ab1.2", as_symbol[*~digit] << double_, ut));
+        BOOST_TEST(test("a,b1.2", as_symbol[~digit % ','] << double_, ut));
+    }
+    
     // typed basic_string rules
     {
         utree ut("buzz");
Modified: trunk/libs/spirit/test/qi/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/utree.cpp	(original)
+++ trunk/libs/spirit/test/qi/utree.cpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,5 +1,6 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
 // Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c)      2010 Bryce Lelbach
 //
 // 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)
@@ -18,7 +19,12 @@
 {
     std::stringstream s;
     s << val;
-    return s.str() == expected + " ";
+    if (s.str() == expected + " ")
+        return true;
+
+    std::cerr << "got result: " << s.str() 
+              << ", expected: " << expected << std::endl;
+    return false;
 }
 
 int main()
@@ -30,13 +36,16 @@
     using boost::spirit::utf8_symbol_type;
     using boost::spirit::utf8_string_type;
 
+    using boost::spirit::qi::real_parser;
+    using boost::spirit::qi::strict_real_policies;
+    using boost::spirit::qi::digit;
     using boost::spirit::qi::char_;
     using boost::spirit::qi::string;
     using boost::spirit::qi::int_;
     using boost::spirit::qi::double_;
     using boost::spirit::qi::space;
     using boost::spirit::qi::rule;
-    using boost::spirit::qi::as_string;
+    using boost::spirit::qi::as;
     using boost::spirit::qi::lexeme;
 
     // primitive data types
@@ -75,7 +84,7 @@
 
     // sequences
     {
-        using boost::spirit::qi::digit;
+        using boost::spirit::qi::as_string;
 
         utree ut;
         BOOST_TEST(test_attr("xy", char_ >> char_, ut) &&
@@ -166,9 +175,6 @@
 
     // alternatives
     {
-        using boost::spirit::qi::real_parser;
-        using boost::spirit::qi::strict_real_policies;
-
         typedef real_parser<double, strict_real_policies<double> >
             strict_double_type;
         strict_double_type const strict_double = strict_double_type();
@@ -212,7 +218,7 @@
 
     // as_string
     {
-        using boost::spirit::qi::digit;
+        using boost::spirit::qi::as_string;
 
         utree ut;
         BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) &&
@@ -244,5 +250,62 @@
         ut.clear();
     }
 
+    // as
+    {
+        typedef as<std::string> as_string_type;
+        as_string_type const as_string = as_string_type();
+
+        typedef as<utf8_symbol_type> as_symbol_type;
+        as_symbol_type const as_symbol = as_symbol_type();
+
+        utree ut;
+        BOOST_TEST(test_attr("xy", as_string[char_ >> char_], ut) &&
+            ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+        ut.clear();
+
+        BOOST_TEST(test_attr("ab1.2", as_string[*~digit] >> double_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("xy", as_string[*char_], ut) &&
+            ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+        ut.clear();
+
+        BOOST_TEST(test_attr("x,y", as_string[char_ >> ',' >> char_], ut) &&
+            ut.which() == utree_type::string_type && check(ut, "\"xy\""));
+        ut.clear();
+
+        BOOST_TEST(test_attr("x,y", char_ >> ',' >> char_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( \"x\" \"y\" )"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("a,b1.2", as_string[~digit % ','] >> double_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( \"ab\" 1.2 )"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
+        ut.clear();
+        
+        BOOST_TEST(test_attr("xy", as_symbol[char_ >> char_], ut) &&
+            ut.which() == utree_type::symbol_type && check(ut, "xy"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("ab1.2", as_symbol[*~digit] >> double_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("xy", as_symbol[*char_], ut) &&
+            ut.which() == utree_type::symbol_type && check(ut, "xy"));
+        ut.clear();
+
+        BOOST_TEST(test_attr("x,y", as_symbol[char_ >> ',' >> char_], ut) &&
+            ut.which() == utree_type::symbol_type && check(ut, "xy"));
+        ut.clear();
+        BOOST_TEST(test_attr("a,b1.2", as_symbol[~digit % ','] >> double_, ut) &&
+            ut.which() == utree_type::list_type && check(ut, "( ab 1.2 )"));
+        ut.clear();
+    }
+
     return boost::report_errors();
 }
Modified: trunk/libs/spirit/test/support/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/test/support/utree_test.cpp	(original)
+++ trunk/libs/spirit/test/support/utree_test.cpp	2010-12-23 16:14:50 EST (Thu, 23 Dec 2010)
@@ -1,6 +1,7 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
     Copyright (c) 2001-2010 Hartmut Kaiser
+    Copyright (c)      2010 Bryce Lelbach
 
     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)
@@ -19,7 +20,12 @@
 {
     std::stringstream s;
     s << val;
-    return (s.str() == expected + " ") ? true : false;
+    if (s.str() == expected + " ")
+        return true;
+
+    std::cerr << "got result: " << s.str() 
+              << ", expected: " << expected << std::endl;
+    return false;
 }
 
 struct one_two_three
@@ -35,6 +41,8 @@
     using boost::spirit::utree;
     using boost::spirit::nil;
     using boost::spirit::uninitialized;
+    using boost::spirit::utf8_symbol_type;
+    using boost::spirit::binary_string_type;
 
     {
         // test the size
@@ -62,6 +70,10 @@
         // single element string
         utree val('x');
         BOOST_TEST(check(val, "\"x\""));
+        
+        // empty string 
+        utree val1("");
+        BOOST_TEST(check(val1, "\"\""));
     }
 
     {
@@ -69,7 +81,7 @@
         BOOST_TEST(check(val, "123.456"));
     }
 
-    {
+    { // strings
         utree val("Hello, World");
         BOOST_TEST(check(val, "\"Hello, World\""));
         utree val2;
@@ -87,6 +99,42 @@
         BOOST_TEST(val4 < val6);
     }
 
+    { // symbols
+        utree val(utf8_symbol_type("Hello, World"));
+        BOOST_TEST(check(val, "Hello, World"));
+        utree val2;
+        val2 = val;
+        BOOST_TEST(check(val2, "Hello, World"));
+        utree val3(utf8_symbol_type("Hello, World. Chuckie is back!!!"));
+        val = val3;
+        BOOST_TEST(check(val, "Hello, World. Chuckie is back!!!"));
+
+        utree val4(utf8_symbol_type("Apple"));
+        utree val5(utf8_symbol_type("Apple"));
+        BOOST_TEST(val4 == val5);
+
+        utree val6(utf8_symbol_type("ApplePie"));
+        BOOST_TEST(val4 < val6);
+    }
+
+    { // binary_strings
+        utree val(binary_string_type("\xDE#\xAD"));
+        BOOST_TEST(check(val, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */));
+        utree val2;
+        val2 = val;
+        BOOST_TEST(check(val2, "#de23ad#" /* FIXME?: "#\xDE#\xAD#" */));
+        utree val3(binary_string_type("\xDE\xAD\xBE\xEF"));
+        val = val3;
+        BOOST_TEST(check(val, "#deadbeef#" /* FIXME?: "#\xDE\xAD\xBE\xEF#" */));
+
+        utree val4(binary_string_type("\x01"));
+        utree val5(binary_string_type("\x01"));
+        BOOST_TEST(val4 == val5);
+
+        utree val6(binary_string_type("\x01\x02"));
+        BOOST_TEST(val4 < val6);
+    }
+
     {
         utree val;
         val.push_back(123);