Boost logo

Boost-Commit :

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;
 }
 //]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk