$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55713 - in sandbox/SOC/2009/unicode: boost/iterator boost/unicode boost/utility libs/unicode/doc libs/unicode/doc/concepts libs/unicode/example
From: loufoque_at_[hidden]
Date: 2009-08-22 04:21:58
Author: mgaunard
Date: 2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
New Revision: 55713
URL: http://svn.boost.org/trac/boost/changeset/55713
Log:
join_iterator + concatenation + various fixes
Added:
   sandbox/SOC/2009/unicode/boost/iterator/join_iterator.hpp   (contents, props changed)
   sandbox/SOC/2009/unicode/boost/unicode/combining.hpp   (contents, props changed)
   sandbox/SOC/2009/unicode/boost/utility/
   sandbox/SOC/2009/unicode/boost/utility/common_type.hpp   (contents, props changed)
   sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc1c.xml   (contents, props changed)
      - copied, changed from r55708, /sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml
Removed:
   sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml
Text files modified: 
   sandbox/SOC/2009/unicode/boost/iterator/consumer_iterator.hpp      |    11 +                                       
   sandbox/SOC/2009/unicode/boost/iterator/pipe_concept.hpp           |     8 -                                       
   sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator.hpp          |   195 ++++++++++++++++++++++++++++++++++----- 
   sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator_fwd.hpp      |     1                                         
   sandbox/SOC/2009/unicode/boost/unicode/cat.hpp                     |   195 ++++++++++++++++++++++++++++++++++++++++
   sandbox/SOC/2009/unicode/boost/unicode/compose_fwd.hpp             |   173 +++++++++++++++++++++-------------      
   sandbox/SOC/2009/unicode/boost/unicode/graphemes.hpp               |    28 ++++-                                   
   sandbox/SOC/2009/unicode/boost/unicode/hangul.hpp                  |     3                                         
   sandbox/SOC/2009/unicode/boost/unicode/pipe_def.hpp                |    72 +++-----------                          
   sandbox/SOC/2009/unicode/boost/unicode/utf.hpp                     |    13 +                                       
   sandbox/SOC/2009/unicode/boost/unicode/utf_codecs.hpp              |    97 +++++++++++++------                     
   sandbox/SOC/2009/unicode/libs/unicode/doc/Jamfile.v2               |    31 +++++                                   
   sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc1c.xml            |     7 +                                       
   sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Consumer.xml    |     1                                         
   sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/OneManyPipe.xml |     2                                         
   sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Pipe.xml        |     4                                         
   sandbox/SOC/2009/unicode/libs/unicode/doc/users_manual.qbk         |     1                                         
   sandbox/SOC/2009/unicode/libs/unicode/example/compose.cpp          |    26 +++++                                   
   18 files changed, 656 insertions(+), 212 deletions(-)
Modified: sandbox/SOC/2009/unicode/boost/iterator/consumer_iterator.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/iterator/consumer_iterator.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/iterator/consumer_iterator.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -9,6 +9,10 @@
 
 #include <boost/iterator/consumer_iterator_fwd.hpp>
 
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/equal_to.hpp>
+
+
 namespace boost
 {
 
@@ -151,15 +155,16 @@
 
 /** Model of \c \xmlonly<conceptname>Consumer</conceptname>\endxmlonly
  * that adapts the elements another \c \xmlonly<conceptname>Consumer</conceptname>\endxmlonly
- * sees with a model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly. */
+ * sees with a model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly, assuming its \c max_output is \c 1. */
 template<typename Pipe, typename Consumer>
 struct piped_consumer
 {
     BOOST_CONCEPT_ASSERT((PipeConcept<Pipe>));
     BOOST_CONCEPT_ASSERT((ConsumerConcept<Consumer>));
-    
     BOOST_CONCEPT_ASSERT((Convertible<typename Pipe::output_type, typename Consumer::input_type>));
     
+    BOOST_MPL_ASSERT(( mpl::equal_to< typename Pipe::max_output, mpl::int_<1> > ));
+    
     typedef typename Pipe::input_type input_type;
     
     piped_consumer() // singular
@@ -204,8 +209,6 @@
     return piped_consumer<Pipe, Consumer>(p, c);
 }
 
-
-
 template<typename It, typename Consumer>
 BOOST_CONCEPT_REQUIRES(
     ((InputIterator<It>))
Added: sandbox/SOC/2009/unicode/boost/iterator/join_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2009/unicode/boost/iterator/join_iterator.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -0,0 +1,381 @@
+#ifndef BOOST_ITERATOR_JOIN_ITERATOR_HPP
+#define BOOST_ITERATOR_JOIN_ITERATOR_HPP
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/range.hpp>
+
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/transform_view.hpp>
+
+#include <boost/fusion/include/mpl.hpp> 
+#include <boost/fusion/tuple.hpp>
+#include <boost/fusion/adapted.hpp>
+#include <boost/fusion/algorithm/transformation/transform.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+
+#include <boost/variant.hpp>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/utility/common_type.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+
+namespace boost
+{
+    
+namespace detail
+{
+    template<typename T, int N>
+    struct wrapper : iterator_facade<
+        wrapper<T, N>,
+        typename std::iterator_traits<T>::value_type,
+        typename std::iterator_traits<T>::iterator_category,
+        typename std::iterator_traits<T>::reference,
+        typename std::iterator_traits<T>::difference_type
+    >
+    {
+        static const int index = N;
+        
+        wrapper() {} // singular
+        
+        wrapper(const T& t_) : t(t_)
+        {
+        }
+        
+    private:
+        friend class boost::iterator_core_access;
+        
+        typename std::iterator_traits<T>::reference
+        dereference() const { return *t; }
+        
+        void increment() { ++t; }
+        void decrement() { --t; }
+        void advance(typename std::iterator_traits<T>::difference_type n) { t += n; }
+        
+        typename std::iterator_traits<T>::difference_type
+        distance_to(const wrapper& other) const { other.t - t; }
+        
+        template<typename U, int M>
+        typename std::iterator_traits<T>::difference_type
+        distance_to(const wrapper<U, M>& other) const { other.t - t; }
+        
+        template<typename U>
+        typename std::iterator_traits<T>::difference_type
+        distance_to(const U& other) const { other - t; }
+        
+        bool equal(const wrapper& other) const { return t == other.t; }
+        
+        template<typename U, int M>
+        bool equal(const wrapper<U, M>& other) const { return t == other.t; }
+        
+        template<typename U>
+        bool equal(const U& other) const { return t == other; }
+        
+        T t;
+    };
+    
+    template<typename F, typename N>
+    struct meta_wrapper
+    {
+        typedef wrapper<F, N::value> type;
+    };
+    
+    template<int N, typename T>
+    wrapper<T, N> make_wrapper(const T& t)
+    {
+        return wrapper<T, N>(t);
+    }
+    
+    struct transform_range
+    {
+        template<typename>
+        struct result
+        {
+        };
+        
+        template<typename R>
+        struct result<transform_range(R)>
+        {
+            typedef iterator_range<
+                typename range_iterator<const typename remove_reference<R>::type>::type
+            > type;
+        };
+        
+        template<typename Range>
+        iterator_range<
+            typename range_iterator<const Range>::type
+        >
+        operator()(const Range& r) const
+        {
+            return make_iterator_range(
+                begin(r),
+                end(r)
+            );
+        }
+    };
+    
+    template<typename RangeSequence>
+    struct deduce_value_type : common_type_seq<
+        mpl::transform_view<
+            RangeSequence,
+            range_value<mpl::_1>
+        >
+    >
+    {
+    };
+    
+    template<typename Iterator>
+    struct reference_type
+    {
+        typedef typename std::iterator_traits<Iterator>::reference type;
+    };
+    
+    template<typename RangeSequence>
+    struct deduce_reference : common_type_seq<
+        mpl::transform_view<
+            RangeSequence,
+            reference_type<
+                range_iterator<mpl::_1>
+            >
+        >
+    >
+    {
+    };
+    
+    template<typename Iterator>
+    struct difference_type
+    {
+        typedef typename std::iterator_traits<Iterator>::difference_type type;
+    };
+    
+    template<typename RangeSequence>
+    struct deduce_difference_type : common_type_seq<
+        mpl::transform_view<
+            RangeSequence,
+            difference_type<
+                range_iterator<mpl::_1>
+            >
+        >
+    >
+    {
+    };
+    
+    template<typename R>
+    struct dereference_visitor : static_visitor<R>
+    {
+        template<typename T>
+        R operator()(const T& t) const
+        {
+            return *t;
+        }
+    };
+    
+    template<typename Tuple, typename Variant>
+    struct increment_visitor : static_visitor<Variant>
+    {
+        increment_visitor(const Tuple& tuple_) : tuple(tuple_) {}
+        
+        template<typename T>
+        typename enable_if_c<
+            T::index+1 == mpl::size<Tuple>::type::value,
+            Variant
+        >::type operator()(T& t) const
+        {
+            return ++t;
+        }
+        
+        template<typename T>
+        typename disable_if_c<
+            T::index+1 == mpl::size<Tuple>::type::value,
+            Variant
+        >::type operator()(T& t) const
+        {
+            if(++t == make_wrapper<T::index>(end(fusion::get<T::index>(tuple))))
+                return make_wrapper<T::index+1>(
+                    begin(
+                        fusion::get<T::index+1>(tuple)
+                    )
+                );
+            return t;
+        }
+        
+        const Tuple& tuple;
+    };
+    
+    template<typename Tuple, typename Variant>
+    struct decrement_visitor : static_visitor<Variant>
+    {
+        decrement_visitor(const Tuple& tuple_) : tuple(tuple_) {}
+
+        template<typename T>
+        typename enable_if_c<
+            T::index == 0,
+            Variant
+        >::type
+        operator()(T& t) const
+        {
+            return --t;
+        }
+        
+        template<typename T>
+        typename disable_if_c<
+            T::index == 0,
+            Variant
+        >::type
+        operator()(T& t) const
+        {
+            if(t == make_wrapper<T::index>(begin(fusion::get<T::index>(tuple))))
+                return make_wrapper<T::index-1>(
+                    prior(
+                        end(
+                            fusion::get<T::index-1>(tuple)
+                        )
+                    )
+                );
+            return --t;
+        }
+        
+        const Tuple& tuple;
+    };
+    
+    struct equal_visitor : static_visitor<bool>
+    {
+        template<typename T1, typename T2>
+        bool operator()(const T1&, const T2&) const
+        {
+            return false;
+        }
+        
+        template<typename T>
+        bool operator()(const T& lft, const T& rgt) const
+        {
+            return lft == rgt;
+        }
+    };
+    
+} // namespace detail
+
+template<typename Tuple>
+struct join_iterator;
+
+template<typename Tuple>
+join_iterator<Tuple> make_join_end_iterator(const Tuple& tuple);
+
+/** Iterator that wraps a tuple of ranges and makes it appear as
+ * a single concatenated range. */
+template<typename Tuple>
+struct join_iterator
+	: iterator_facade<
+		join_iterator<Tuple>,
+        typename detail::deduce_value_type<typename fusion::result_of::as_vector<typename fusion::result_of::transform<const Tuple, detail::transform_range>::type const>::type>::type,
+		std::bidirectional_iterator_tag,
+        typename detail::deduce_reference<typename fusion::result_of::as_vector<typename fusion::result_of::transform<const Tuple, detail::transform_range>::type const>::type>::type,
+        typename detail::deduce_difference_type<typename fusion::result_of::as_vector<typename fusion::result_of::transform<const Tuple, detail::transform_range>::type const>::type>::type
+	>
+{
+    join_iterator() {} // singular
+    
+    join_iterator(const Tuple& t_) : t(fusion::transform(t_, detail::transform_range())), v(detail::make_wrapper<0>(begin(fusion::get<0>(t))))
+    {
+    }
+    
+private:
+    join_iterator(const Tuple& t_, bool) : t(fusion::transform(t_, detail::transform_range())), v(detail::make_wrapper<mpl::size<FusionTuple>::value-1>(end(fusion::get<mpl::size<FusionTuple>::value-1>(t))))
+    {
+    }
+    
+    friend join_iterator<Tuple> make_join_end_iterator<Tuple>(const Tuple& tuple);
+	friend class boost::iterator_core_access;
+    typedef typename fusion::result_of::as_vector<typename fusion::result_of::transform<const Tuple, detail::transform_range>::type const>::type FusionTuple;
+    typedef typename detail::deduce_reference<FusionTuple>::type Reference;
+
+	Reference dereference() const
+	{
+		return apply_visitor(
+            detail::dereference_visitor<Reference>(),
+            v
+        );
+	}
+	
+	void increment()
+	{
+        v = apply_visitor(detail::increment_visitor<FusionTuple, Variant>(t), v);
+	}
+	
+	void decrement()
+	{
+        v = apply_visitor(detail::decrement_visitor<FusionTuple, Variant>(t), v);
+	}
+	
+	bool equal(const join_iterator& other) const
+	{
+		return apply_visitor(detail::equal_visitor(), v, other.v);
+	}
+    
+    FusionTuple t;
+    typedef typename make_variant_over<
+        typename mpl::fold<
+            FusionTuple,
+            mpl::vector<>,
+            mpl::push_back<
+                mpl::_1,
+                mpl::quote2<detail::meta_wrapper>::apply<
+                    range_iterator<mpl::_2>,
+                    mpl::size<mpl::_1>
+                >
+            >
+        >::type
+    >::type Variant;
+    Variant v;
+};
+
+template<typename Tuple>
+join_iterator<Tuple> make_join_iterator(const Tuple& tuple)
+{
+    return join_iterator<Tuple>(tuple);
+}
+
+template<typename Tuple>
+join_iterator<Tuple> make_join_end_iterator(const Tuple& tuple)
+{
+    return join_iterator<Tuple>(tuple, true);
+}
+
+template<typename Tuple>
+iterator_range<
+    join_iterator<Tuple>
+> joined(const Tuple& tuple)
+{
+    return make_iterator_range(
+        make_join_iterator(tuple),
+        make_join_end_iterator(tuple)
+    );
+}
+
+#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
+template<typename... T>
+iterator_range<
+    join_iterator< tuple<T...> >
+> joined_n(const T&... n);
+#else
+#define BOOST_ITERATOR_JOIN_DEF(z, n, text) \
+template<BOOST_PP_ENUM_PARAMS(n, typename T)> \
+iterator_range< \
+    join_iterator< tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
+> joined_n(BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
+{ \
+    return joined(make_tuple(BOOST_PP_ENUM_PARAMS(n, t))); \
+}
+BOOST_PP_REPEAT_FROM_TO(1, 4, BOOST_ITERATOR_JOIN_DEF, ~)
+#endif
+
+} // namespace boost
+
+#endif
Modified: sandbox/SOC/2009/unicode/boost/iterator/pipe_concept.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/iterator/pipe_concept.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/iterator/pipe_concept.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -35,10 +35,8 @@
 
 /** Concept checking class for the \c OneManyPipe concept */
 template<typename X>
-struct OneManyPipeConcept : DefaultConstructible<X>, CopyConstructible<X>
+struct OneManyPipeConcept : PipeConcept<X>
 {
-    typedef typename X::input_type input_type;
-    typedef typename X::output_type output_type;
     
     BOOST_CONCEPT_USAGE(OneManyPipeConcept)
     {
@@ -47,9 +45,9 @@
     }
     
 private:
-    typedef output_iterator_archetype<output_type> out_type;
+    typedef output_iterator_archetype<typename PipeConcept<X>::output_type> out_type;
     
-    input_type in;
+    typename PipeConcept<X>::input_type in;
     out_type out;
 };
 
Modified: sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -14,29 +14,27 @@
 
 #include <boost/iterator/pipe_iterator_fwd.hpp>
 
+#include <boost/type_traits.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/equal_to.hpp>
+
 namespace boost
 {
 
-/** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
- * constructed from a model of \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly. */
+/** CRTP Utility to define a \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly. */
 template<typename OneManyPipe>
-struct one_many_pipe : OneManyPipe
+struct one_many_pipe
 {
-    BOOST_CONCEPT_ASSERT((OneManyPipeConcept<OneManyPipe>));
-    
-    one_many_pipe() {} // singular
-    
-	one_many_pipe(OneManyPipe p_) : OneManyPipe(p_)
-	{
-	}
-	
         template<typename In, typename Out>
         std::pair<In, Out>
         ltr(In begin, In end, Out out)
         {
                 BOOST_ASSERT(begin != end);
                 
-		out = OneManyPipe::operator()(*begin, out);
+		out = static_cast<OneManyPipe&>(*this)(*begin, out);
                 return std::make_pair(++begin, out);
         }
         
@@ -46,24 +44,18 @@
         {
                 BOOST_ASSERT(begin != end);
                 
-		out = OneManyPipe::operator()(*--end, out);
+		out = static_cast<OneManyPipe&>(*this)(*--end, out);
                 return std::make_pair(end, out);
         }
 };
 
-template<typename OneManyPipe>
-BOOST_CONCEPT_REQUIRES(
-    ((OneManyPipeConcept<OneManyPipe>)),
-    (one_many_pipe<OneManyPipe>)
-) make_one_many_pipe(OneManyPipe p)
-{
-	return one_many_pipe<OneManyPipe>(p);
-}
-
-/* TODO: make it work for pipes that don't expose max_output */
+/* TODO: Make it work for types that don't expose max_output */
 /** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
  * constructed from two models of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
- * and that applies one after the other. */
+ * and that applies one after the other.
+ * 
+ * The second pipe must require less input than the output of the first per
+ * step for it to work. */
 template<typename P1, typename P2>
 struct multi_pipe
 {
@@ -84,7 +76,50 @@
     multi_pipe(P1 p1_, P2 p2_ = P2()) : p1(p1_), p2(p2_) {}
     
     template<typename In, typename Out>
-    std::pair<In, Out> ltr(In begin, In end, Out out)
+    typename enable_if<
+        mpl::and_<
+            is_base_of<
+                std::forward_iterator_tag,
+                typename std::iterator_traits<Out>::iterator_category
+            >,
+            is_same<
+                typename P1::output_type,
+                typename P2::output_type
+            >
+        >,
+        std::pair<In, Out>
+    >::type
+    ltr(In begin, In end, Out out)
+    {
+        Out b = out;
+        
+        std::pair<In, Out> pair = p1.ltr(begin, end, out);
+        Out e = pair.second;
+        
+        do
+        {
+            tie(b, out) = p2.ltr(b, e, out);
+        }
+        while(b != e);
+        
+        return std::make_pair(pair.first, out);
+    }
+    
+    template<typename In, typename Out>
+    typename disable_if<
+        mpl::and_<
+            is_base_of<
+                std::forward_iterator_tag,
+                typename std::iterator_traits<Out>::iterator_category
+            >,
+            is_same<
+                typename P1::output_type,
+                typename P2::output_type
+            >
+        >,
+        std::pair<In, Out>
+    >::type
+    ltr(In begin, In end, Out out)
     {
         typename P1::output_type buf[max_output::value];
         typename P1::output_type* b = buf;
@@ -102,7 +137,48 @@
     }
     
     template<typename In, typename Out>
-    std::pair<In, Out> rtl(In begin, In end, Out out)
+    typename enable_if<
+        mpl::and_<
+            is_base_of<
+                std::forward_iterator_tag,
+                typename std::iterator_traits<Out>::iterator_category
+            >,
+            is_same<
+                typename P1::output_type,
+                typename P2::output_type
+            >
+        >,
+        std::pair<In, Out>
+    >::type rtl(In begin, In end, Out out)
+    {
+        Out b = out;
+        
+        std::pair<In, Out> pair = p1.rtl(begin, end, out);
+        Out e = pair.second;
+        
+        do
+        {
+            tie(b, out) = p2.ltr(b, e, out);
+        }
+        while(b != e);
+        
+        return std::make_pair(pair.first, out);
+    }
+    
+    template<typename In, typename Out>
+    typename disable_if<
+        mpl::and_<
+            is_base_of<
+                std::forward_iterator_tag,
+                typename std::iterator_traits<Out>::iterator_category
+            >,
+            is_same<
+                typename P1::output_type,
+                typename P2::output_type
+            >
+        >,
+        std::pair<In, Out>
+    >::type rtl(In begin, In end, Out out)
     {
         typename P1::output_type buf[max_output::value];
         typename P1::output_type* b = buf;
@@ -135,10 +211,75 @@
     return multi_pipe<P1, P2>(p1, p2);
 }
 
+/** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
+ * that adapts the elements another \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
+ * sees with a model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly, assuming its \c max_output is \c 1. */
+template<typename P1, typename P2>
+struct piped_pipe : P2
+{
+    BOOST_CONCEPT_ASSERT((PipeConcept<P1>));
+    BOOST_CONCEPT_ASSERT((PipeConcept<P2>));
+    
+    BOOST_CONCEPT_ASSERT((Convertible<typename P1::output_type, typename P2::input_type>));
+    
+    BOOST_MPL_ASSERT(( mpl::equal_to< typename P1::max_output, mpl::int_<1> > ));
+    
+    typedef typename P1::input_type input_type;
+    typedef typename P2::output_type output_type;
+    
+    piped_pipe() {}
+    piped_pipe(P1 p1_, P2 p2_ = P2()) : P2(p2_), p1(p1_) {}
+    
+    template<typename In, typename Out>
+    std::pair<In, Out> ltr(In begin, In end, Out out)
+    {
+        std::pair<
+            pipe_iterator<In, P1>,
+            Out
+        > pair = P2::ltr(
+            make_pipe_iterator(begin, end, begin, p1),
+            make_pipe_iterator(begin, end, end, p1),
+            out
+        );
+        
+        return std::make_pair(pair.first.base(), pair.second);
+    }
+    
+    template<typename In, typename Out>
+    std::pair<In, Out> rtl(In begin, In end, Out out)
+    {
+        std::pair<
+            pipe_iterator<In, P1>,
+            Out
+        > pair = P2::rtl(
+            make_pipe_iterator(begin, end, begin, p1),
+            make_pipe_iterator(begin, end, end, p1),
+            out
+        );
+        return std::make_pair(pair.first.base(), pair.second);
+    }
+    
+private:
+    P1 p1;
+};
+
+template<typename P1, typename P2>
+BOOST_CONCEPT_REQUIRES(
+    ((PipeConcept<P1>))
+    ((PipeConcept<P2>))
+    ((Convertible<typename P1::output_type, typename P2::input_type>)),
+    (piped_pipe<P1, P2>)
+) make_piped_pipe(P1 p1, P2 p2)
+{
+    return piped_pipe<P1, P2>(p1, p2);
+}
+
+
+
 /** Model of \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly
  * that casts its input to its template parameter and writes it to its output. */
 template<typename T>
-struct cast_pipe
+struct cast_pipe : one_many_pipe< cast_pipe<T> >
 {
     typedef T input_type;
     typedef T output_type;
Modified: sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator_fwd.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator_fwd.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/iterator/pipe_iterator_fwd.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -123,7 +123,6 @@
                 return pos;
         }
 
-private:
         typedef typename Pipe::output_type T;
 
         friend class boost::iterator_core_access;
Modified: sandbox/SOC/2009/unicode/boost/unicode/cat.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/cat.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/cat.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -1,6 +1,201 @@
 #ifndef BOOST_UNICODE_CAT_HPP
 #define BOOST_UNICODE_CAT_HPP
 
+#include <boost/unicode/compose.hpp>
+#include <boost/unicode/utf.hpp>
+#include <boost/unicode/combining.hpp>
 
+#include <algorithm>
+#include <boost/utility.hpp>
+
+#include <boost/iterator/join_iterator.hpp>
+
+#include <boost/range/algorithm/copy.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#if defined(BOOST_UNICODE_DOXYGEN_INVOKED) || !defined(BOOST_NO_RVALUE_REFERENCES)
+/** INTERNAL ONLY */
+#define BOOST_UNICODE_FWD_2(macro) \
+    macro(,&&,,&&)
+#else
+#define BOOST_UNICODE_FWD_2(macro) \
+    macro(,&,,&) \
+    macro(,&,const,&) \
+    macro(const,&,,&) \
+    macro(const,&,const,&)
+#endif
+
+namespace boost
+{
+namespace unicode
+{
+    
+namespace detail
+{
+    template<typename ValueType, typename OutputIterator>
+    pipe_output_iterator<
+        OutputIterator,
+        utf_encoder<ValueType>
+    > utf_encoded_out(OutputIterator out)
+    {
+	    return piped_output(out, utf_encoder<ValueType>());
+    }
+
+} // namespace detail
+
+/** INTERNAL ONLY */
+#define BOOST_UNICODE_CAT_LIMITS_FWD(cv1, ref1, cv2, ref2) \
+/** Partitions the two input ranges into a total of four ranges,
+   the two inner ranges requiring transformation to maintain a certain
+   normalization form while concatenated. */ \
+template<typename Range1, typename Range2> \
+tuple< \
+    sub_range<cv1 Range1>, \
+    sub_range<cv1 Range1>, \
+    sub_range<cv2 Range2>, \
+    sub_range<cv2 Range2> \
+> \
+cat_limits(cv1 Range1 ref1 range1, cv2 Range2 ref2 range2) \
+{ \
+    iterator_range< \
+        pipe_iterator< \
+            typename range_iterator<cv2 Range2>::type, \
+            utf_decoder \
+        > \
+    > decoded2 = utf_decoded(range2); \
+\
+    char32 ch = *begin(decoded2); \
+    if(ucd::get_combining_class(ch) != 0) \
+    { \
+        iterator_range< \
+            pipe_iterator< \
+                typename range_iterator<cv1 Range1>::type, \
+                utf_decoder \
+            > \
+        > decoded1 = utf_decoded(range1); \
+\
+\
+        typename range_iterator<cv1 Range1>::type \
+        new_end = combiner().rtl(begin(decoded1), end(decoded1)).base(); \
+\
+        typename range_iterator<cv2 Range2>::type \
+        new_begin = combiner().ltr(begin(decoded2), end(decoded2)).base(); \
+\
+        return make_tuple( \
+            make_iterator_range(begin(range1), new_end), \
+            make_iterator_range(new_end, end(range1)), \
+            make_iterator_range(begin(range2), new_begin), \
+            make_iterator_range(new_begin, end(range2)) \
+        ); \
+    } \
+\
+    return make_tuple( \
+        range1, \
+        make_iterator_range(end(range1), end(range1)), \
+        make_iterator_range(end(range2), end(range2)), \
+        range2 \
+    ); \
+}
+BOOST_UNICODE_FWD_2(BOOST_UNICODE_CAT_LIMITS_FWD)
+    
+/** Concatenates two ranges of UTF code units and puts the result in \c out.
+ * 
+ * Throws \c std::out_of_range if the input or resulting strings are not stream-safe.
+ * \pre \c Range1 and \c Range2 are in Normalized Form D, have the same value type and are non-empty.
+ * \post \c out is in Normalized Form D and is stream-safe. */
+template<typename Range1, typename Range2, typename OutputIterator>
+OutputIterator decomposed_concat(const Range1& range1, const Range2& range2, OutputIterator out)
+{
+    tuple<
+        sub_range<const Range1>,
+        sub_range<const Range1>,
+        sub_range<const Range2>,
+        sub_range<const Range2>
+    >
+    t = cat_limits(range1, range2);
+    
+    out = copy(t.get<0>(), out);
+    out = pipe(joined_n(utf_decoded(t.get<1>()), utf_decoded(t.get<2>())), combine_sorter(), detail::utf_encoded_out<typename range_value<const Range1>::type>(out)).base();
+    return copy(t.get<3>(), out);
+}
+
+/** Concatenates two ranges of UTF code units and puts the result in \c out.
+ * 
+ * Throws \c std::out_of_range if the input or resulting strings are not stream-safe.
+ * \pre \c Range1 and \c Range2 are in Normalized Form C, have the same value type and are non-empty.
+ * \post \c out is in Normalized Form C and is stream-safe. */
+template<typename Range1, typename Range2, typename OutputIterator>
+OutputIterator composed_concat(const Range1& range1, const Range2& range2, OutputIterator out, unsigned mask = BOOST_UNICODE_OPTION(ucd::decomposition_type::canonical))
+{
+    tuple<
+        sub_range<const Range1>,
+        sub_range<const Range1>,
+        sub_range<const Range2>,
+        sub_range<const Range2>
+    >
+    t = cat_limits(range1, range2);
+    
+    out = copy(t.get<0>(), out);
+    out = pipe(joined_n(t.get<1>(), t.get<2>()), make_piped_pipe(utf_decoder(), normalizer(mask)), detail::utf_encoded_out<typename range_value<const Range1>::type>(out)).base();
+    return copy(t.get<3>(), out);
+}
+
+/** INTERNAL ONLY */
+#define BOOST_UNICODE_COMPOSED_CONCATED_FWD(cv1, ref1, cv2, ref2) \
+template<typename Range1, typename Range2> \
+iterator_range< \
+    join_iterator< \
+        tuple< \
+            sub_range<cv1 Range1>, \
+            iterator_range< \
+                pipe_iterator< \
+                    join_iterator< \
+                        tuple< \
+                            sub_range<cv1 Range1>, \
+                            sub_range<cv2 Range2> \
+                        > \
+                    >, \
+                    piped_pipe< \
+                        utf_decoder, \
+                        multi_pipe< \
+                            normalizer, \
+                            utf_encoder<typename range_value<cv1 Range1>::type> \
+                        > \
+                    > \
+                > \
+            >, \
+            sub_range<cv1 Range2> \
+        > \
+    > \
+> composed_concated(cv1 Range1 ref1 range1, cv2 Range2 ref2 range2, unsigned mask = BOOST_UNICODE_OPTION(ucd::decomposition_type::canonical)) \
+{ \
+    tuple< \
+        sub_range<cv1 Range1>, \
+        sub_range<cv1 Range1>, \
+        sub_range<cv2 Range2>, \
+        sub_range<cv2 Range2> \
+    > \
+    t = cat_limits(range1, range2); \
+     \
+    return joined_n( \
+        t.get<0>(), \
+        piped( \
+            joined_n(t.get<1>(), t.get<2>()), \
+            make_piped_pipe( \
+                utf_decoder(), \
+                make_multi_pipe( \
+                    normalizer(mask), \
+                    utf_encoder<typename range_value<cv1 Range1>::type>() \
+                ) \
+            ) \
+        ), \
+        t.get<3>() \
+    ); \
+}
+BOOST_UNICODE_FWD_2(BOOST_UNICODE_COMPOSED_CONCATED_FWD)
+
+    
+} // namespace unicode
+} // namespace boost
 
 #endif
Added: sandbox/SOC/2009/unicode/boost/unicode/combining.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2009/unicode/boost/unicode/combining.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -0,0 +1,208 @@
+#ifndef BOOST_UNICODE_COMBINING_HPP
+#define BOOST_UNICODE_COMBINING_HPP
+
+#include <boost/config.hpp>
+#include <boost/iterator/consumer_iterator.hpp>
+#include <boost/cuchar.hpp>
+#include <algorithm>
+
+#include <boost/throw_exception.hpp>
+#include <stdexcept>
+#ifndef BOOST_NO_STD_LOCALE
+#include <sstream>
+#include <ios>
+#endif
+
+#include <boost/type_traits.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost
+{
+namespace unicode
+{
+
+/** Maximum size of a combining character sequence in a stream-safe Unicode string */
+typedef mpl::int_<31> combining_max;
+
+namespace detail
+{
+    struct combining_pred
+    {
+        bool operator()(char32 lft, char32 rgt) const
+        {
+            return ucd::get_combining_class(lft) < ucd::get_combining_class(rgt);
+        }
+    };
+    
+    template<typename Size, typename Iterator, typename Comp>
+    void stable_sort_bounded(Iterator begin, Iterator end, Comp comp = std::less<typename std::iterator_traits<Iterator>::value_type>())
+    {
+#if defined(__GLIBCPP__) || defined(__GLIBCXX__) || defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) 
+        typename std::iterator_traits<Iterator>::value_type buf[Size::value];
+        return std::__stable_sort_adaptive(begin, end, buf, Size::value, comp);
+#else
+        return std::stable_sort(begin, end, comp);
+#endif
+    }
+    
+    template<typename Iterator>
+    void not_stream_safe(Iterator begin, Iterator end)
+    {
+#ifndef BOOST_NO_STD_LOCALE
+	    std::stringstream ss;
+	    ss << "Invalid Unicode stream-safe combining character sequence " << std::showbase << std::hex;
+	    for(Iterator it = begin; it != end; ++it)
+		    ss << *it << " ";
+	    ss << "encountered while trying to decompose UTF-32 sequence";
+	    std::out_of_range e(ss.str());
+#else
+	    std::out_of_range e("Invalid Unicode stream-safe combining character sequence encountered while trying to decompose UTF-32 sequence");
+#endif
+	    boost::throw_exception(e);
+    }
+    
+    template<typename Iterator, typename OutputIterator>
+    OutputIterator copy_bounded(Iterator begin, Iterator end, OutputIterator first, OutputIterator last)
+    {
+        for(Iterator it = begin; it != end; ++it)
+        {
+            if(first == last)
+                not_stream_safe(begin, end);
+            
+            *first++ = *it;
+        }
+        return first;
+    }
+
+} // namespace detail
+
+/** Model of \c \xmlonly<conceptname>Consumer</conceptname>\endxmlonly
+ * that consumes combining character sequences. */
+struct combiner
+{
+    typedef char32 input_type;
+    typedef char32 output_type;
+    
+    template<typename Iterator>
+    Iterator ltr(Iterator begin, Iterator end)
+    {
+        do
+        {
+            ++begin;
+        }
+        while(begin != end && ucd::get_combining_class(*begin) != 0);
+        return begin;
+    }
+    
+    template<typename Iterator>
+    Iterator rtl(Iterator begin, Iterator end)
+    {
+        while(end != begin && ucd::get_combining_class(*--end) != 0);
+        return end;
+    }
+};
+
+struct combine_sorter
+{
+    typedef char32 input_type;
+    typedef char32 output_type;
+    typedef combining_max max_output;
+    
+    template<typename In, typename Out>
+    std::pair<In, Out> ltr(In begin, In end, Out out)
+    {
+        return combine_sort_impl(
+            *make_consumer_iterator(begin, end, begin, combiner()),
+            out
+        );
+    }
+    
+    template<typename In, typename Out>
+    std::pair<In, Out> rtl(In begin, In end, Out out)
+    {
+        std::pair<
+            reverse_iterator<In>,
+            Out
+        > p = combine_sort_impl(
+            make_reversed_range(
+                *prior(
+                    make_consumer_iterator(begin, end, end, combiner())
+                )
+            ),
+            out
+        );
+        
+        return std::make_pair(p.first.base(), p.second);
+    }
+    
+private:
+    template<typename Range, typename Out>
+    std::pair<typename range_iterator<const Range>::type, Out> combine_sort_impl(const Range& range, Out out)
+    {
+        return std::make_pair(end(range), combine_sort_impl(begin(range), end(range), out));
+    }
+
+    template<typename In, typename Out>
+    typename enable_if<
+        is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<Out>::iterator_category
+        >,
+        Out
+    >::type
+    combine_sort_impl(In begin, In end, Out out)
+    {
+        Out out_pos = detail::copy_bounded(begin, end, out, out + max_output::value);
+        detail::stable_sort_bounded<max_output>(out, out_pos, detail::combining_pred());
+        return out_pos;
+    }
+    
+    template<typename In, typename Out>
+    typename disable_if<
+        is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<Out>::iterator_category
+        >,
+        Out
+    >::type
+    combine_sort_impl(In begin, In end, Out out)
+    {
+        char32 buffer[max_output::value];
+        char32* out_pos = detail::copy_bounded(begin, end, buffer, buffer + max_output::value);
+        detail::stable_sort_bounded<max_output>(buffer, out_pos, detail::combining_pred());
+        return std::copy(buffer, out_pos, out);
+    }
+};
+
+#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
+/** Turns a range of code points into a range of subranges of code points,
+ * each subrange being a combining character sequence. */
+template<typename Range>
+iterator_range<
+    consumer_iterator<typename range_iterator<Range>::type, combiner>
+>
+combine_bounded(Range&& range);
+#else
+template<typename Range>
+iterator_range<
+    consumer_iterator<typename range_iterator<const Range>::type, combiner>
+>
+combine_bounded(const Range& range)
+{
+    return consumed(range, combiner());
+}
+
+template<typename Range>
+iterator_range<
+    consumer_iterator<typename range_iterator<Range>::type, combiner>
+>
+combine_bounded(Range& range)
+{
+    return consumed(range, combiner());
+}
+#endif
+    
+} // namespace unicode
+} // namespace boost
+
+#endif
Modified: sandbox/SOC/2009/unicode/boost/unicode/compose_fwd.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/compose_fwd.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/compose_fwd.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -3,22 +3,21 @@
 
 #include <boost/unicode/ucd/properties.hpp>
 #include <boost/unicode/hangul.hpp>
+#include <boost/unicode/combining.hpp>
 
 #include <boost/integer/static_pow.hpp>
 #include <climits>
 
 #include <vector>
 
-#include <boost/throw_exception.hpp>
-#include <stdexcept>
-#ifndef BOOST_NO_STD_LOCALE
-#include <sstream>
-#include <ios>
-#endif
-
 #include <boost/detail/unspecified.hpp>
 #include <boost/iterator/pipe_iterator.hpp>
 
+#include <boost/range/adaptor/reversed.hpp>
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits.hpp>
+
 namespace boost
 {
 namespace unicode
@@ -30,30 +29,6 @@
 #undef BOOST_UNICODE_OPTION
 #endif
 
-namespace detail
-{
-    struct combining_pred
-    {
-        bool operator()(char32 lft, char32 rgt) const
-        {
-            return ucd::get_combining_class(lft) < ucd::get_combining_class(rgt);
-        }
-    };
-    
-    template<typename Size, typename Iterator, typename Comp>
-    void stable_sort_bounded(Iterator begin, Iterator end, Comp comp = std::less<typename std::iterator_traits<Iterator>::value_type>())
-    {
-#if defined(__GLIBCPP__) || defined(__GLIBCXX__) || defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) 
-        typename std::iterator_traits<Iterator>::value_type buf[Size::value];
-        return std::__stable_sort_adaptive(begin, end, buf, Size::value, comp);
-#else
-        return std::stable_sort(begin, end, comp);
-#endif
-    }
-
-}
-
-/* TODO: special case the case when Out is a RandomAccessIterator */
 /** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
  * that decomposes a combining character sequence, i.e. it transforms a combining
  * character sequence into its canonically ordered decomposed equivalent.
@@ -64,26 +39,69 @@
     typedef char32 input_type;
     typedef char32 output_type;
     
-    typedef mpl::int_<31> max_output;
+    typedef combining_max max_output;
     
     decomposer(unsigned mask_ = BOOST_UNICODE_OPTION(ucd::decomposition_type::canonical)) : mask(mask_)
     {
     }
     
     /** Throws \c std::out_of_range if [<tt>begin</tt>, <tt>end</tt>[ is not stream-safe.
-     * \post \c out is in Normalization Form D. */
+     * \post \c out is in Normalization Form D and is stream-safe. */
     template<typename In, typename Out>
-    std::pair<In, Out> ltr(In begin, In end, Out out, bool inverse = false)
+    std::pair<In, Out> ltr(In begin, In end, Out out)
     {
-        In pos = begin;
+        return decompose_impl(
+            *make_consumer_iterator(begin, end, begin, combiner()),
+            out
+        );
+    }
+    
+    /** Throws \c std::out_of_range if [<tt>begin</tt>, <tt>end</tt>[ is not stream-safe.
+     * \post \c out is in Normalization Form D and is stream-safe. */
+    template<typename In, typename Out>
+    std::pair<In, Out> rtl(In begin, In end, Out out)
+    {   
+        std::pair<
+            reverse_iterator<In>,
+            Out
+        > p = decompose_impl(
+            make_reversed_range(
+                *prior(
+                    make_consumer_iterator(begin, end, end, combiner())
+                )
+            ),
+            out
+        );
         
+        return std::make_pair(p.first.base(), p.second);
+    }
+    
+private:
+    template<typename Range, typename Out>
+    std::pair<typename range_iterator<const Range>::type, Out> decompose_impl(const Range& range, Out out)
+    {
+        return std::make_pair(end(range), decompose_impl(begin(range), end(range), out));
+    }
+    
+    template<typename In, typename Out>
+    typename disable_if<
+        is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<Out>::iterator_category
+        >,
+        Out
+    >::type
+    decompose_impl(In begin, In end, Out out)
+    {
         char32 buf[max_output::value];
         char32* out_pos = buf;
         
         bool to_sort = false;
-        do
+        
+        for(In pos = begin; pos != end; ++pos)
         {
             char32 ch = *pos;
+
             if(ucd::get_combining_class(ch) != 0)
                 to_sort = true;
         
@@ -98,7 +116,7 @@
                 if((out_pos + hangul_decomposer::len(ch) - 1) != (buf + max_output::value))
                     out_pos = hangul_decomposer()(ch, out_pos);
                 else
-                    not_stream_safe(begin, end);
+                    detail::not_stream_safe(begin, end);
             }
             else if(out_pos != (buf + max_output::value))
             {
@@ -106,47 +124,65 @@
             }
             else
             {
-                not_stream_safe(begin, end);
+                detail::not_stream_safe(begin, end);
             }
-            
-            ++pos;
         }
-        while(pos != end && ((!inverse && ucd::get_combining_class(*pos) != 0) || (inverse && ucd::get_combining_class(*pos) == 0)));
         
         if(to_sort)
             detail::stable_sort_bounded<max_output>(buf, out_pos, detail::combining_pred());
 
         out = std::copy(buf, out_pos, out);
-        return std::make_pair(pos, out);
+        return out;
     }
     
-    /** Throws \c std::out_of_range if [<tt>begin</tt>, <tt>end</tt>[ is not stream-safe.
-     * \post \c out is in Normalization Form D. */
     template<typename In, typename Out>
-    std::pair<In, Out> rtl(In begin, In end, Out out)
+    typename enable_if<
+        is_base_of<
+            std::random_access_iterator_tag,
+            typename std::iterator_traits<Out>::iterator_category
+        >,
+        Out
+    >::type
+    decompose_impl(In begin, In end, Out out)
     {
-        std::pair<
-            reverse_iterator<In>,
-            Out
-        > p = ltr(make_reverse_iterator(end), make_reverse_iterator(begin), out, true);
-        return std::make_pair(p.first.base(), p.second);
-    }
-    
-private:
-    template<typename Iterator>
-    static void not_stream_safe(Iterator begin, Iterator end)
-    {
-#ifndef BOOST_NO_STD_LOCALE
-	    std::stringstream ss;
-	    ss << "Invalid Unicode stream-safe combining character sequence " << std::showbase << std::hex;
-	    for(Iterator it = begin; it != end; ++it)
-		    ss << *it << " ";
-	    ss << "encountered while trying to decompose UTF-32 sequence";
-	    std::out_of_range e(ss.str());
-#else
-	    std::out_of_range e("Invalid Unicode stream-safe combining character sequence encountered while trying to decompose UTF-32 sequence");
-#endif
-	    boost::throw_exception(e);
+        char32* out_pos = out;
+        
+        bool to_sort = false;
+        
+        for(In pos = begin; pos != end; ++pos)
+        {
+            char32 ch = *pos;
+
+            if(ucd::get_combining_class(ch) != 0)
+                to_sort = true;
+        
+            iterator_range<const char32*> dec = ucd::get_decomposition(ch);
+            if(!empty(dec) && ((1 << ucd::get_decomposition_type(ch)) & mask))
+            {
+                for(const char32* p = boost::begin(dec); p != boost::end(dec); ++p)
+                    out_pos = decompose_rec(*p, out_pos);
+            }
+            else if(BOOST_UNICODE_OPTION(ucd::decomposition_type::canonical) & mask)
+            {
+                if((out_pos + hangul_decomposer::len(ch) - 1) != (out + max_output::value))
+                    out_pos = hangul_decomposer()(ch, out_pos);
+                else
+                    detail::not_stream_safe(begin, end);
+            }
+            else if(out_pos != (out + max_output::value))
+            {
+                *out_pos++ = ch;
+            }
+            else
+            {
+                detail::not_stream_safe(begin, end);
+            }
+        }
+        
+        if(to_sort)
+            detail::stable_sort_bounded<max_output>(out, out_pos, detail::combining_pred());
+
+        return out_pos;
     }
     
     template<typename OutputIterator>
@@ -311,6 +347,9 @@
     }
 };
 
+/** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly
+ * that decomposes using a mask and then recomposes canonically a
+ * sequence of code points. */
 typedef boost::detail::unspecified< multi_pipe<decomposer, composer> >::type normalizer;
 
 } // namespace unicode
Modified: sandbox/SOC/2009/unicode/boost/unicode/graphemes.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/graphemes.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/graphemes.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -37,9 +37,13 @@
     }
 };
 
+#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** Adapts the range of code points \c range into a range of ranges of code points,
  * each subrange being a grapheme cluster. */
 template<typename Range>
+detail::unspecified<void> grapheme_bounded(Range&& range);
+#else
+template<typename Range>
 iterator_range<typename boost::detail::unspecified<
     consumer_iterator<
         typename range_iterator<const Range>::type,
@@ -51,8 +55,6 @@
     return consumed(range, make_boundary_consumer(unicode::grapheme_boundary()));
 }
 
-/** Adapts the range of code points \c range into a range of ranges of code points,
- * each subrange being a grapheme cluster. */
 template<typename Range>
 iterator_range<typename boost::detail::unspecified<
     consumer_iterator<
@@ -64,12 +66,26 @@
 {
     return consumed(range, make_boundary_consumer(unicode::grapheme_boundary()));
 }
+#endif
 
+#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** INTERNAL ONLY */
 #define BOOST_UNICODE_GRAPHEME_BOUNDED_DEF(Name)                       \
 /** Adapts the range of Name units \c range into a range of ranges of
 Name units, each subrange being a grapheme cluster. */                 \
 template<typename Range>                                               \
+detail::unspecified<void> Name##_grapheme_bounded(Range&& range);      \
+                                                                       \
+/** Model of \c \xmlonly<conceptname>BoundaryChecker</conceptname>\endxmlonly
+that tells whether a position lies on a grapheme cluster boundary
+within a range of Name units. */                                       \
+typedef multi_boundary<                                                \
+    Name##_boundary, Name##_decoder,                                   \
+    grapheme_boundary                                                  \
+> Name##_grapheme_boundary;            
+#else
+#define BOOST_UNICODE_GRAPHEME_BOUNDED_DEF(Name)                       \
+template<typename Range>                                               \
 iterator_range<typename boost::detail::unspecified<                    \
     consumer_iterator<                                                 \
         typename range_iterator<const Range>::type,                    \
@@ -90,8 +106,6 @@
     );                                                                 \
 }                                                                      \
                                                                        \
-/** Adapts the range of Name units \c range into a range of ranges of
-Name units, each subrange being a grapheme cluster. */                 \
 template<typename Range>                                               \
 iterator_range<typename boost::detail::unspecified<                    \
     consumer_iterator<                                                 \
@@ -113,13 +127,11 @@
     );                                                                 \
 }                                                                      \
                                                                        \
-/** Model of \c \xmlonly<conceptname>BoundaryChecker</conceptname>\endxmlonly
-that tells whether a position lies on a grapheme cluster boundary
-within a range of Name units. */                                       \
 typedef multi_boundary<                                                \
     Name##_boundary, Name##_decoder,                                   \
     grapheme_boundary                                                  \
-> Name##_grapheme_boundary;                                            \
+> Name##_grapheme_boundary;                                            
+#endif
 
 BOOST_UNICODE_GRAPHEME_BOUNDED_DEF(u16)
 BOOST_UNICODE_GRAPHEME_BOUNDED_DEF(u8)
Modified: sandbox/SOC/2009/unicode/boost/unicode/hangul.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/hangul.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/hangul.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -7,6 +7,7 @@
 
 #include <boost/cuchar.hpp>
 #include <boost/mpl/int.hpp>
+#include <boost/iterator/pipe_iterator.hpp>
 
 namespace boost
 {
@@ -30,7 +31,7 @@
  * transforms a single Hangul syllable (LV or LVT) into its decomposed
  * form since those decompositions are not part of the UCD.
  * Other code points are left unchanged. */
-struct hangul_decomposer
+struct hangul_decomposer : one_many_pipe<hangul_decomposer>
 {
     typedef char32 input_type;
     typedef char32 output_type;
Modified: sandbox/SOC/2009/unicode/boost/unicode/pipe_def.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/pipe_def.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/pipe_def.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -13,26 +13,6 @@
 
 #include <boost/iterator/pipe_iterator.hpp>
 
-namespace boost
-{
-
-/** INTERNAL ONLY */    
-template<typename Pipe>
-struct identity_pipe : Pipe
-{
-    identity_pipe() {}
-    identity_pipe(Pipe p) : Pipe(p) {}
-};
-
-/** INTERNAL ONLY */
-template<typename Pipe>
-identity_pipe<Pipe> make_identity_pipe(Pipe p)
-{
-    return identity_pipe<Pipe>(p);
-}
-
-}
-
 #ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** INTERNAL ONLY */
 #define BOOST_UNICODE_PIPE_EAGER_DEF(z, n, text) \
@@ -44,11 +24,11 @@
 #else
 #define BOOST_UNICODE_PIPE_EAGER_DEF(z, n, text) \
 template<typename Range, typename OutputIterator BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename T)> \
-OutputIterator BOOST_PP_TUPLE_ELEM(2, 0, text)(const Range& range, OutputIterator out BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
+OutputIterator text(const Range& range, OutputIterator out BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
 { \
     return pipe( \
         range, \
-        BOOST_PP_CAT(make_, BOOST_PP_TUPLE_ELEM(2, 1, text))(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), r)(BOOST_PP_ENUM_PARAMS(n, t))), \
+        BOOST_PP_CAT(text, r)(BOOST_PP_ENUM_PARAMS(n, t)), \
         out \
     ); \
 }
@@ -61,63 +41,45 @@
    adapter that wraps the range \c range and converts it step-by-step as
    the range is advanced. */ \
 template<typename Range, typename... T> \
-detail::unspecified<void> BOOST_PP_CAT(text, d)(const Range& range, const T&... args);
+detail::unspecified<void> BOOST_PP_CAT(text, d)(Range&& range, const T&... args);
 #else
 #define BOOST_UNICODE_PIPE_LAZY_DEF(z, n, text) \
 template<typename Range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename T)> \
 iterator_range< \
     pipe_iterator< \
         typename range_iterator<const Range>::type, \
-        BOOST_PP_TUPLE_ELEM(2, 1, text) < \
-            unicode::BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), r) \
-        > \
+        unicode::BOOST_PP_CAT(text, r) \
     > \
 > \
-BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), d)(const Range& range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
+BOOST_PP_CAT(text, d)(const Range& range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
 { \
-    return piped(range, BOOST_PP_CAT(make_, BOOST_PP_TUPLE_ELEM(2, 1, text))(unicode::BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), r)(BOOST_PP_ENUM_PARAMS(n, t)))); \
+    return piped(range, unicode::BOOST_PP_CAT(text, r)(BOOST_PP_ENUM_PARAMS(n, t))); \
 }
 #endif
 
 #ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** INTERNAL ONLY */
-#define BOOST_UNICODE_PIPE_LAZY_2_DEF(z, n, text) \
-/** Lazily evalutes \c unicode::##text##r by returning a range
-   adapter that wraps the range \c range and converts it step-by-step as
-   the range is advanced. */ \
-template<typename Range, typename... T> \
-detail::unspecified<void> BOOST_PP_CAT(text, d)(Range& range, const T&... args);
+#define BOOST_UNICODE_PIPE_LAZY_2_DEF(z, n, text) 
 #else
 #define BOOST_UNICODE_PIPE_LAZY_2_DEF(z, n, text) \
 template<typename Range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename T)> \
 iterator_range< \
     pipe_iterator< \
         typename range_iterator<Range>::type, \
-        BOOST_PP_TUPLE_ELEM(2, 1, text) < \
-            unicode::BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), r) \
-        > \
+        unicode::BOOST_PP_CAT(text, r) \
     > \
 > \
-BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), d)(Range& range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
+BOOST_PP_CAT(text, d)(Range& range BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & t)) \
 { \
-    return piped(range, BOOST_PP_CAT(make_, BOOST_PP_TUPLE_ELEM(2, 1, text))(unicode::BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, text), r)(BOOST_PP_ENUM_PARAMS(n, t)))); \
+    return piped(range, unicode::BOOST_PP_CAT(text, r)(BOOST_PP_ENUM_PARAMS(n, t))); \
 }
 #endif
 
-#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
-/** INTERNAL ONLY */
-#define BOOST_UNICODE_REPEAT(n, macro, tuple) \
-BOOST_PP_REPEAT(n, macro, BOOST_PP_TUPLE_ELEM(2, 0, tuple))
-#else
-#define BOOST_UNICODE_REPEAT(n, macro, tuple) \
-BOOST_PP_REPEAT(n, macro, tuple)
-#endif
-
 /** INTERNAL ONLY */
-#define BOOST_UNICODE_PIPE_COMMON_DEF(name, wrapper, n) \
-BOOST_UNICODE_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_EAGER_DEF, (name, wrapper)) \
-BOOST_UNICODE_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_LAZY_DEF, (name, wrapper)) \
-BOOST_UNICODE_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_LAZY_2_DEF, (name, wrapper))
+#define BOOST_UNICODE_PIPE_COMMON_DEF(name, n) \
+BOOST_PP_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_EAGER_DEF, name) \
+BOOST_PP_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_LAZY_DEF, name) \
+BOOST_PP_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_LAZY_2_DEF, name)
 
 #ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** INTERNAL ONLY */
@@ -145,8 +107,8 @@
  * \arg \c name Name of the type modelling the \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly.
  * \arg \c n Maximum number of optional arguments. */
 #define BOOST_UNICODE_ONE_MANY_PIPE_DEF(name, n) \
-BOOST_UNICODE_PIPE_COMMON_DEF(name, one_many_pipe, n) \
-BOOST_UNICODE_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_OUTPUT_DEF, name)
+BOOST_UNICODE_PIPE_COMMON_DEF(name, n) \
+BOOST_PP_REPEAT(BOOST_PP_INC(n), BOOST_UNICODE_PIPE_OUTPUT_DEF, name)
 
 /** Defines helper functions for usage of a \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly.
  * Helper functions provide a pseudo-variadic interface where they forward all the extra arguments to
@@ -154,6 +116,6 @@
  * \arg \c name Name of the type modelling the \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly.
  * \arg \c n Maximum number of optional arguments. */
 #define BOOST_UNICODE_PIPE_DEF(name, n) \
-BOOST_UNICODE_PIPE_COMMON_DEF(name, identity_pipe, n)
+BOOST_UNICODE_PIPE_COMMON_DEF(name, n)
 
 #endif
Modified: sandbox/SOC/2009/unicode/boost/unicode/utf.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/utf.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/utf.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -18,13 +18,19 @@
 
 /* */
 
+#ifdef BOOST_UNICODE_DOXYGEN_INVOKED
 /** INTERNAL ONLY */
 #define BOOST_UNICODE_DECODER_DEF(Name)                                \
 BOOST_UNICODE_PIPE_DEF(Name##_decode, 0)                               \
-                                                                       \
 /** Adapts the range of Name units \c range into a range of ranges of
 Name units, each subrange being a decoded unit. */                     \
 template<typename Range>                                               \
+detail::unspecified<void> Name##_bounded(Range&& range);
+#else
+#define BOOST_UNICODE_DECODER_DEF(Name)                                \
+BOOST_UNICODE_PIPE_DEF(Name##_decode, 0)                               \
+                                                                       \
+template<typename Range>                                               \
 iterator_range<typename boost::detail::unspecified<                    \
     consumer_iterator<                                                 \
         typename range_iterator<const Range>::type,                    \
@@ -38,8 +44,6 @@
     );                                                                 \
 }                                                                      \
                                                                        \
-/** Adapts the range of Name units \c range into a range of ranges of
-Name units, each subrange being a decoded unit. */                     \
 template<typename Range>                                               \
 iterator_range<typename boost::detail::unspecified<                    \
     consumer_iterator<                                                 \
@@ -52,7 +56,8 @@
         range,                                                         \
         make_pipe_consumer(unicode::Name##_decoder())                  \
     );                                                                 \
-}                                                                      \
+}                                                                      
+#endif
 
 BOOST_UNICODE_ENCODER_DEF(u16)
 BOOST_UNICODE_DECODER_DEF(u16)
Modified: sandbox/SOC/2009/unicode/boost/unicode/utf_codecs.hpp
==============================================================================
--- sandbox/SOC/2009/unicode/boost/unicode/utf_codecs.hpp	(original)
+++ sandbox/SOC/2009/unicode/boost/unicode/utf_codecs.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -78,7 +78,7 @@
 
 /** Model of \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly
  * that converts a code point to a sequence of UTF-16 code units. */
-struct u16_encoder
+struct u16_encoder : one_many_pipe<u16_encoder>
 {
     typedef char32 input_type;
         typedef char16 output_type;
@@ -217,7 +217,7 @@
 
 /** Model of \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly
  * that converts a code point to a sequence of UTF-8 code units. */
-struct u8_encoder
+struct u8_encoder : one_many_pipe<u8_encoder>
 {
     typedef char32 input_type;
         typedef char output_type;
@@ -403,36 +403,73 @@
 namespace detail
 {
 
-template<typename T, typename Enable = void>
-struct is_u32 : mpl::false_ {};
-template<> struct is_u32<char32> : mpl::true_ {};
-template<typename T>
-struct is_u32<T, typename enable_if<
-    mpl::and_<
-        is_same<T, wchar_t>,
-        mpl::bool_<sizeof(T) == 4>
-    >
->::type> : mpl::true_ {};
-
-template<typename T, typename Enable = void>
-struct is_u16 : mpl::false_ {};
-template<> struct is_u16<char16> : mpl::true_ {};
-template<typename T>
-struct is_u16<T, typename enable_if<
-    mpl::and_<
-        is_same<T, wchar_t>,
-        mpl::bool_<sizeof(T) == 2>
-    >
->::type> : mpl::true_ {};
-
-template<typename T, typename Enable = void>
-struct is_u8 : mpl::false_ {};
-template<> struct is_u8<char> : mpl::true_ {};
+    template<typename T, typename Enable = void>
+    struct is_u32 : mpl::false_ {};
+    template<> struct is_u32<char32> : mpl::true_ {};
+    template<typename T>
+    struct is_u32<T, typename enable_if<
+        mpl::and_<
+            is_same<T, wchar_t>,
+            mpl::bool_<sizeof(T) == 4>
+        >
+    >::type> : mpl::true_ {};
+
+    template<typename T, typename Enable = void>
+    struct is_u16 : mpl::false_ {};
+    template<> struct is_u16<char16> : mpl::true_ {};
+    template<typename T>
+    struct is_u16<T, typename enable_if<
+        mpl::and_<
+            is_same<T, wchar_t>,
+            mpl::bool_<sizeof(T) == 2>
+        >
+    >::type> : mpl::true_ {};
+
+    template<typename T, typename Enable = void>
+    struct is_u8 : mpl::false_ {};
+    template<> struct is_u8<char> : mpl::true_ {};
+
+    template<typename ValueType, typename Enable = void>
+    struct select_encoder
+    {
+    };
+    
+    template<typename ValueType>
+    struct select_encoder<ValueType, typename enable_if<
+        detail::is_u32<ValueType>
+    >::type>
+    {
+        typedef cast_pipe<char32> type;
+    };
+    
+    template<typename ValueType>
+    struct select_encoder<ValueType, typename enable_if<
+        detail::is_u16<ValueType>
+    >::type>
+    {
+        typedef u16_encoder type;
+    };
+    
+    template<typename ValueType>
+    struct select_encoder<ValueType, typename enable_if<
+        detail::is_u8<ValueType>
+    >::type>
+    {
+        typedef u8_encoder type;
+    };
 
 } // namespace detail
 
+/** Model of \c \xmlonly<conceptname>OneManyPipe</conceptname>\endxmlonly,
+ * either behaves like \c u16_encoder, a \c u8_encoder depending on the
+ * targeted element type \c ValueType. */
+template<typename ValueType>
+struct utf_encoder : detail::select_encoder<ValueType>::type
+{
+};
+
 /** Model of \c \xmlonly<conceptname>Pipe</conceptname>\endxmlonly,
- * either behaves like \c u16_decoder or \c u8_decoder depending on the
+ * either behaves like \c u16_decoder, a \c u8_decoder or nothing depending on the
  * value type of the input range. */
 struct utf_decoder
 {
@@ -454,7 +491,7 @@
         >
     >::type>
     {
-        typedef one_many_pipe< cast_pipe<char32> > type;
+        typedef cast_pipe<char32> type;
     };
     
     template<typename Iterator>
@@ -490,7 +527,7 @@
     std::pair<In, Out>
         rtl(In begin, In end, Out out)
     {
-        return typename decoder<In>::type().ltr(begin, end, out);
+        return typename decoder<In>::type().rtl(begin, end, out);
     }
 };
 
Added: sandbox/SOC/2009/unicode/boost/utility/common_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2009/unicode/boost/utility/common_type.hpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -0,0 +1,113 @@
+#ifndef BOOST_UTILITY_COMMON_TYPE_HPP
+#define BOOST_UTILITY_COMMON_TYPE_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/type_traits.hpp>
+
+namespace boost
+{
+    
+namespace detail
+{
+    template<int, typename A, typename>
+    struct Sel
+    {
+        typedef A type;
+    };
+    
+    template<typename A, typename B>
+    struct Sel<2, A, B>
+    {
+        typedef B type;
+    };
+    
+    template<typename A, typename B>
+    struct most_converted_type
+    {
+        static char (&deduce(const A&))[1];
+        static char (&deduce(const B&))[2];
+        typedef typename Sel<sizeof deduce(0 ? *(A*)0 : *(B*)0), A, B>::type type;
+    };
+    
+    template<typename A>
+    struct most_converted_type<A, A>
+    {
+        typedef A type;
+    };
+    
+    template<typename A>
+    struct most_converted_type<A, const A>
+    {
+        typedef A type;
+    };
+    
+    template<typename A>
+    struct most_converted_type<const A, A> : most_converted_type<A, const A>
+    {
+    };
+    
+    template<typename A>
+    struct most_converted_type<A, void>
+    {
+        typedef A type;
+    };
+    
+    template<typename A>
+    struct most_converted_type<void, A> : most_converted_type<A, void>
+    {
+    };
+
+} // namespace detail
+    
+    template<typename T, typename U>
+    struct common_type2
+    {
+        typedef typename mpl::if_<
+            mpl::and_<
+                is_reference<T>,
+                mpl::and_<
+                    is_reference<U>,
+                    is_same<
+                        typename remove_cv<typename remove_reference<T>::type>::type,
+                        typename remove_cv<typename remove_reference<U>::type>::type
+                    >
+                >
+            >,
+            typename add_reference<
+                typename mpl::if_<
+                    mpl::or_<
+                        is_const<typename remove_reference<T>::type>,
+                        is_const<typename remove_reference<U>::type>
+                    >,
+                    typename add_const<
+                        typename detail::most_converted_type<
+                            typename remove_reference<T>::type,
+                            typename remove_reference<U>::type
+                        >::type
+                    >::type,
+                    typename detail::most_converted_type<
+                        typename remove_reference<T>::type,
+                        typename remove_reference<U>::type
+                    >::type
+                >::type
+            >::type,
+            typename detail::most_converted_type<
+                typename remove_reference<T>::type,
+                typename remove_reference<U>::type
+            >::type
+        >::type type;
+    };
+    
+    template<typename Sequence>
+    struct common_type_seq : mpl::fold<
+        Sequence,
+        typename mpl::front<Sequence>::type,
+        common_type2<mpl::_1, mpl::_2>
+    >
+    {
+    };
+} // namespace boost
+
+#endif
Modified: sandbox/SOC/2009/unicode/libs/unicode/doc/Jamfile.v2
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/Jamfile.v2	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/Jamfile.v2	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -18,19 +18,42 @@
 
 boostbook quickbook
     :
-        users_manual.qbk autodoc2.xml
+        users_manual.qbk
     :
                 <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
         <format>pdf:<xsl:param>img.src.path=$(images)/
-        <dependency>autodoc
+        <dependency>autodoc1
+        <dependency>autodoc2
     ;
 
-doxygen autodoc 
+doxygen autodoc1
+    :
+        [ path.glob-tree ../../../boost/iterator : pipe_*.hpp consumer_*.hpp join_*.hpp : .svn detail ]
+	:
+        <xsl:param>boost.doxygen.reftitle="Iterator/Range reference"
+    
+        <doxygen:param>EXTRACT_ALL=YES
+        <doxygen:param>"PREDEFINED=BOOST_UNICODE_DOXYGEN_INVOKED \\
+                                   \"BOOST_UNICODE_DECL= \" \\
+                                   \"BOOST_CONCEPT_REQUIRES(a,b)=/** Requires: a */ b \""
+        <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+        <doxygen:param>EXTRACT_PRIVATE=NO
+        <doxygen:param>ENABLE_PREPROCESSING=YES
+        <doxygen:param>MACRO_EXPANSION=YES
+#        <doxygen:param>EXPAND_ONLY_PREDEF=YES
+        <doxygen:param>SEARCH_INCLUDES=YES
+        <doxygen:param>"INCLUDE_PATH=$(BOOST_ROOT) \\
+                                     ../../../"
+	;
+    
+doxygen autodoc2
     :
-        [ path.glob-tree ../../../boost/iterator : pipe_*.hpp consumer_*.hpp : .svn detail ]
                 [ path.glob-tree ../../../boost/unicode : *.hpp : .svn detail ]
         ../../../boost/cuchar.hpp
         :
+        <xsl:param>boost.doxygen.reftitle="Unicode reference"
+
+    
         <doxygen:param>EXTRACT_ALL=YES
         <doxygen:param>"PREDEFINED=BOOST_UNICODE_DOXYGEN_INVOKED \\
                                    \"BOOST_UNICODE_DECL= \" \\
Copied: sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc1c.xml (from r55708, /sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml)
==============================================================================
--- /sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc1c.xml	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -1,9 +1,12 @@
 <?xml version="1.0" standalone="yes"?>
-<library-reference xmlns:xi="http://www.w3.org/2001/XInclude">
+<library-reference xmlns:xi="http://www.w3.org/2001/XInclude" id="iterator_range_reference">
+<title>Iterator/Range reference</title>
+
 <xi:include href="concepts/Pipe.xml"/>
 <xi:include href="concepts/OneManyPipe.xml"/>
 <xi:include href="concepts/Consumer.xml"/>
 <xi:include href="concepts/BoundaryChecker.xml"/>
 
-<xi:include href="autodoc.xml"/>
+<xi:include href="autodoc1.xml"/>
+
 </library-reference>
Deleted: sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/autodoc2.xml	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
+++ (empty file)
@@ -1,9 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<library-reference xmlns:xi="http://www.w3.org/2001/XInclude">
-<xi:include href="concepts/Pipe.xml"/>
-<xi:include href="concepts/OneManyPipe.xml"/>
-<xi:include href="concepts/Consumer.xml"/>
-<xi:include href="concepts/BoundaryChecker.xml"/>
-
-<xi:include href="autodoc.xml"/>
-</library-reference>
Modified: sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Consumer.xml
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Consumer.xml	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Consumer.xml	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -102,6 +102,7 @@
     <apply-template name="boost::boundary_consumer">
         <type name="BoundaryChecker"/>
     </apply-template>
+    <type name="boost::unicode::combiner" />
   </example-model>
 
 </concept>
Modified: sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/OneManyPipe.xml
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/OneManyPipe.xml	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/OneManyPipe.xml	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -69,6 +69,8 @@
     the function object.</simpara>
     </description>
   </associated-type>
+  
+  <refines const="no" concept="Pipe"/>
 
   <valid-expression name="Construction">
     <construct template-parameters="">
Modified: sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Pipe.xml
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Pipe.xml	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/concepts/Pipe.xml	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -135,10 +135,6 @@
   </valid-expression>  
 
   <example-model>
-    <apply-template name="boost::one_many_pipe">
-        <type name="OneManyPipe"/>
-    </apply-template>
-  
     <type name="boost::unicode::u8_decoder" />
     <type name="boost::unicode::u16_decoder" />
     <type name="boost::unicode::hangul_composer" />
Modified: sandbox/SOC/2009/unicode/libs/unicode/doc/users_manual.qbk
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/doc/users_manual.qbk	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/doc/users_manual.qbk	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -454,6 +454,7 @@
 
 [endsect]
 
+[xinclude autodoc1c.xml]
 [xinclude autodoc2.xml]
 
 [section Acknowledgements]
Modified: sandbox/SOC/2009/unicode/libs/unicode/example/compose.cpp
==============================================================================
--- sandbox/SOC/2009/unicode/libs/unicode/example/compose.cpp	(original)
+++ sandbox/SOC/2009/unicode/libs/unicode/example/compose.cpp	2009-08-22 04:21:54 EDT (Sat, 22 Aug 2009)
@@ -9,12 +9,16 @@
 #include <iostream>
 #include <iterator>
 
+#include <boost/unicode/cat.hpp>
+
 #include <boost/range/adaptor/reversed.hpp>
+#include <boost/range/algorithm/copy.hpp>
 #include <boost/assign/list_of.hpp> 
 
 namespace unicode = boost::unicode;
 namespace ucd = unicode::ucd;
 using boost::assign::list_of; 
+using boost::char32;
 
 int main()
 {
@@ -55,6 +59,28 @@
     boost::char32 bar[] = { 0x20, 0x308 };
     std::cout << "Canonical composition of { " << boost::as_array(bar) << " }: ";
     unicode::compose(bar, std::ostream_iterator<boost::char32>(std::cout, " "));
+    std::cout << std::endl << std::endl;
+    
+    //unicode::decomposed_concat(list_of<char32>(0x48)(0x65)(0x304)(0x301), list_of<char32>(0x330)(0x49), std::ostream_iterator<boost::char32>(std::cout, " "));
+    std::cout << std::endl;
+    
+    boost::char32 tmp[] = {0x48, 0x1e17};
+    boost::iterator_range<
+        boost::pipe_iterator<
+            boost::char32*,
+            unicode::decomposer
+        >
+    > r = unicode::decomposed(tmp);
+    
+    std::cout << "Distance: " << std::distance(
+        begin(r),
+        prior(end(r))
+    ) << std::endl;
+    
+    boost::char32 tmp2[] = {0x330, 0x49};
+    unicode::composed_concat(list_of<char32>(0x48)(0x1e17), list_of<char32>(0x330)(0x49), std::ostream_iterator<boost::char32>(std::cout, " "));
     std::cout << std::endl;
+    
+    std::cout << unicode::composed_concated(tmp, tmp2) << std::endl;
 }
 //]