$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81746 - in trunk: boost/spirit/home/karma/detail libs/spirit/test libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2012-12-06 12:41:56
Author: hkaiser
Date: 2012-12-06 12:41:53 EST (Thu, 06 Dec 2012)
New Revision: 81746
URL: http://svn.boost.org/trac/boost/changeset/81746
Log:
Spirit: applying Karma unicode patch
Added:
   trunk/libs/spirit/test/karma/regression_unicode_char.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/karma/detail/output_iterator.hpp |    39 ++++++++++++++++++++++++++------------- 
   trunk/libs/spirit/test/Jamfile                           |     1 +                                       
   2 files changed, 27 insertions(+), 13 deletions(-)
Modified: trunk/boost/spirit/home/karma/detail/output_iterator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/output_iterator.hpp	(original)
+++ trunk/boost/spirit/home/karma/detail/output_iterator.hpp	2012-12-06 12:41:53 EST (Thu, 06 Dec 2012)
@@ -22,6 +22,10 @@
 #include <boost/spirit/home/support/iterators/ostream_iterator.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 
+#if defined(BOOST_MSVC) && defined(BOOST_SPIRIT_UNICODE)
+#include <boost/spirit/home/support/char_encoding/unicode.hpp>
+#endif
+
 namespace boost { namespace spirit { namespace karma { namespace detail 
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -64,7 +68,7 @@
 
         template <typename T>
         void output(T const& value) 
-        { 
+        {
             // track position in the output 
             track_position_data.output(value);
         }
@@ -110,7 +114,7 @@
         }
 
         void output() 
-        { 
+        {
             ++count; 
         }
         std::size_t get_count() const { return count; }
@@ -147,7 +151,7 @@
 
         template <typename T>
         void output(T const&) 
-        { 
+        {
             // count characters, if appropriate
             if (NULL != count)
                 count->output();
@@ -172,24 +176,33 @@
     ///////////////////////////////////////////////////////////////////////////
     class buffer_sink : boost::noncopyable
     {
+       // wchar_t is only 16-bits on Windows. If BOOST_SPIRIT_UNICODE is
+       // defined, the character type is 32-bits wide so we need to make
+       // sure the buffer is at least that wide.
+#if defined(BOOST_MSVC) && defined(BOOST_SPIRIT_UNICODE)
+       typedef spirit::char_encoding::unicode::char_type buffer_char_type;
+#else
+       typedef wchar_t buffer_char_type;
+#endif
+
     public:
         buffer_sink()
           : width(0) {}
 
         ~buffer_sink() 
-        { 
+        {
             tidy(); 
         }
 
         void enable(std::size_t width_) 
-        { 
+        {
             tidy();             // release existing buffer
             width = (width_ == std::size_t(-1)) ? 0 : width_;
             buffer.reserve(width); 
         }
 
         void tidy() 
-        { 
+        {
             buffer.clear(); 
             width = 0; 
         }
@@ -197,18 +210,18 @@
         template <typename T>
         void output(T const& value)
         {
-            BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(wchar_t));
+            BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(buffer_char_type));
             buffer.push_back(value);
         }
 
         template <typename OutputIterator_>
         bool copy(OutputIterator_& sink, std::size_t maxwidth) const 
-        { 
+        {
 #if defined(BOOST_MSVC)
 #pragma warning(push)
 #pragma warning(disable: 4267)
 #endif
-            typename std::basic_string<wchar_t>::const_iterator end = 
+            typename std::basic_string<buffer_char_type>::const_iterator end = 
                 buffer.begin() + (std::min)(buffer.size(), maxwidth);
 
 #if defined(BOOST_MSVC)
@@ -219,12 +232,12 @@
         }
         template <typename RestIterator>
         bool copy_rest(RestIterator& sink, std::size_t start_at) const 
-        { 
+        {
 #if defined(BOOST_MSVC)
 #pragma warning(push)
 #pragma warning(disable: 4267)
 #endif
-            typename std::basic_string<wchar_t>::const_iterator begin = 
+            typename std::basic_string<buffer_char_type>::const_iterator begin = 
                 buffer.begin() + (std::min)(buffer.size(), start_at);
 
 #if defined(BOOST_MSVC)
@@ -235,13 +248,13 @@
         }
 
         std::size_t buffer_size() const 
-        { 
+        {
             return buffer.size();
         }
 
     private:
         std::size_t width;
-        std::basic_string<wchar_t> buffer;
+        std::basic_string<buffer_char_type> buffer;
     };
 
     ///////////////////////////////////////////////////////////////////////////
Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile	(original)
+++ trunk/libs/spirit/test/Jamfile	2012-12-06 12:41:53 EST (Thu, 06 Dec 2012)
@@ -251,6 +251,7 @@
      [ run karma/regression_center_alignment.cpp           : : : :  karma_regression_center_alignment ]
      [ run karma/regression_container_variant_sequence.cpp : : : :  karma_regression_container_variant_sequence ]
      [ run karma/regression_real_0.cpp                     : : : :  karma_regression_real_0 ]
+     [ run karma/regression_unicode_char.cpp               : : : :  karma_regression_unicode_char ]
 
     ;
 
Added: trunk/libs/spirit/test/karma/regression_unicode_char.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/karma/regression_unicode_char.cpp	2012-12-06 12:41:53 EST (Thu, 06 Dec 2012)
@@ -0,0 +1,63 @@
+//  Copyright (c) 2012 David Bailey
+//  Copyright (c) 2001-2012 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)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifndef BOOST_SPIRIT_UNICODE
+#define BOOST_SPIRIT_UNICODE
+#endif
+
+#include <boost/spirit/home/karma/nonterminal/grammar.hpp>
+#include <boost/spirit/home/karma/nonterminal/rule.hpp>
+#include <boost/spirit/home/karma/char.hpp>
+
+#include "test.hpp"
+
+using namespace spirit_test;
+
+///////////////////////////////////////////////////////////////////////////////
+template <typename OutputIterator>
+struct unicode_char_grammar_
+  : public boost::spirit::karma::grammar<
+        OutputIterator, boost::spirit::char_encoding::unicode::char_type()>
+{
+    unicode_char_grammar_() : unicode_char_grammar_::base_type(thechar)
+    {
+        using boost::spirit::karma::unicode::char_;
+        thechar = char_;
+    }
+
+    boost::spirit::karma::rule<
+        OutputIterator, boost::spirit::char_encoding::unicode::char_type()
+    > thechar;
+};
+
+int
+main()
+{
+    using namespace boost::spirit;
+
+    {
+        typedef std::basic_string<char_encoding::unicode::char_type> unicode_string;
+        typedef std::back_insert_iterator<unicode_string> unicode_back_insert_iterator_type;
+
+        using namespace boost::spirit::unicode;
+
+        BOOST_TEST(test("x", char_, 'x'));
+        BOOST_TEST(test(L"x", char_, L'x'));
+
+        char_encoding::unicode::char_type unicodeCharacter = 0x00000078u;
+        std::basic_string<char_encoding::unicode::char_type> expected;
+        expected.push_back(unicodeCharacter);
+
+        unicode_char_grammar_<unicode_back_insert_iterator_type> unichar;
+
+        BOOST_TEST(test(expected, unichar, unicodeCharacter));
+    }
+
+    return boost::report_errors();
+}