2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_LOCALE_BOUNDARY_INDEX_HPP_INCLUDED
9 #define BOOST_LOCALE_BOUNDARY_INDEX_HPP_INCLUDED
11 #include <boost/locale/config.hpp>
12 #include <boost/locale/boundary/types.hpp>
13 #include <boost/locale/boundary/facets.hpp>
14 #include <boost/locale/boundary/segment.hpp>
15 #include <boost/locale/boundary/boundary_point.hpp>
16 #include <boost/iterator/iterator_facade.hpp>
17 #include <boost/type_traits/is_same.hpp>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/cstdint.hpp>
20 #include <boost/assert.hpp>
22 # pragma warning(push)
23 # pragma warning(disable : 4275 4251 4231 4660)
40 /// \defgroup boundary Boundary Analysis
42 /// This module contains all operations required for %boundary analysis of text: character, word, like and sentence boundaries
51 template<typename IteratorType,typename CategoryType = typename std::iterator_traits<IteratorType>::iterator_category>
52 struct mapping_traits {
53 typedef typename std::iterator_traits<IteratorType>::value_type char_type;
54 static index_type map(boundary_type t,IteratorType b,IteratorType e,std::locale const &l)
56 std::basic_string<char_type> str(b,e);
57 return std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size());
61 template<typename CharType,typename SomeIteratorType>
62 struct linear_iterator_traits {
63 static const bool is_linear =
64 is_same<SomeIteratorType,CharType*>::value
65 || is_same<SomeIteratorType,CharType const*>::value
66 || is_same<SomeIteratorType,typename std::basic_string<CharType>::iterator>::value
67 || is_same<SomeIteratorType,typename std::basic_string<CharType>::const_iterator>::value
68 || is_same<SomeIteratorType,typename std::vector<CharType>::iterator>::value
69 || is_same<SomeIteratorType,typename std::vector<CharType>::const_iterator>::value
75 template<typename IteratorType>
76 struct mapping_traits<IteratorType,std::random_access_iterator_tag> {
78 typedef typename std::iterator_traits<IteratorType>::value_type char_type;
82 static index_type map(boundary_type t,IteratorType b,IteratorType e,std::locale const &l)
87 // Optimize for most common cases
89 // C++0x requires that string is continious in memory and all known
90 // string implementations
91 // do this because of c_str() support.
94 if(linear_iterator_traits<char_type,IteratorType>::is_linear && b!=e)
96 char_type const *begin = &*b;
97 char_type const *end = begin + (e-b);
98 index_type tmp=std::use_facet<boundary_indexing<char_type> >(l).map(t,begin,end);
102 std::basic_string<char_type> str(b,e);
103 index_type tmp = std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size());
110 template<typename BaseIterator>
113 typedef BaseIterator base_iterator;
114 typedef typename std::iterator_traits<base_iterator>::value_type char_type;
117 mapping(boundary_type type,
120 std::locale const &loc)
122 index_(new index_type()),
126 index_type idx=details::mapping_traits<base_iterator>::map(type,begin,end,loc);
134 index_type const &index() const
139 base_iterator begin() const
144 base_iterator end() const
150 boost::shared_ptr<index_type> index_;
151 base_iterator begin_,end_;
154 template<typename BaseIterator>
155 class segment_index_iterator :
156 public boost::iterator_facade<
157 segment_index_iterator<BaseIterator>,
158 segment<BaseIterator>,
159 boost::bidirectional_traversal_tag,
160 segment<BaseIterator> const &
164 typedef BaseIterator base_iterator;
165 typedef mapping<base_iterator> mapping_type;
166 typedef segment<base_iterator> segment_type;
168 segment_index_iterator() : current_(0,0),map_(0)
172 segment_index_iterator(base_iterator p,mapping_type const *map,rule_type mask,bool full_select) :
175 full_select_(full_select)
179 segment_index_iterator(bool is_begin,mapping_type const *map,rule_type mask,bool full_select) :
182 full_select_(full_select)
190 segment_type const &dereference() const
195 bool equal(segment_index_iterator const &other) const
197 return map_ == other.map_ && current_.second == other.current_.second;
202 std::pair<size_t,size_t> next = current_;
204 next.first = next.second;
205 while(next.second < size()) {
207 if(valid_offset(next.second))
210 if(next.second == size())
211 next.first = next.second - 1;
214 while(next.second < size()) {
215 next.first = next.second;
217 if(valid_offset(next.second))
221 update_current(next);
226 std::pair<size_t,size_t> next = current_;
228 while(next.second >1) {
230 if(valid_offset(next.second))
233 next.first = next.second;
234 while(next.first >0) {
236 if(valid_offset(next.first))
241 while(next.second >1) {
243 if(valid_offset(next.second))
246 next.first = next.second - 1;
248 update_current(next);
255 current_.first = size() - 1;
256 current_.second = size();
257 value_ = segment_type(map_->end(),map_->end(),0);
261 current_.first = current_.second = 0;
262 value_ = segment_type(map_->begin(),map_->begin(),0);
266 void set(base_iterator p)
268 size_t dist=std::distance(map_->begin(),p);
269 index_type::const_iterator b=map_->index().begin(),e=map_->index().end();
270 index_type::const_iterator
271 boundary_point=std::upper_bound(b,e,break_info(dist));
272 while(boundary_point != e && (boundary_point->rule & mask_)==0)
275 current_.first = current_.second = boundary_point - b;
278 while(current_.first > 0) {
280 if(valid_offset(current_.first))
285 if(current_.first > 0)
288 value_.first = map_->begin();
289 std::advance(value_.first,get_offset(current_.first));
290 value_.second = value_.first;
291 std::advance(value_.second,get_offset(current_.second) - get_offset(current_.first));
296 void update_current(std::pair<size_t,size_t> pos)
298 std::ptrdiff_t first_diff = get_offset(pos.first) - get_offset(current_.first);
299 std::ptrdiff_t second_diff = get_offset(pos.second) - get_offset(current_.second);
300 std::advance(value_.first,first_diff);
301 std::advance(value_.second,second_diff);
308 if(current_.second != size()) {
309 value_.rule(index()[current_.second].rule);
312 size_t get_offset(size_t ind) const
315 return index().back().offset;
316 return index()[ind].offset;
319 bool valid_offset(size_t offset) const
322 || offset == size() // make sure we not acess index[size]
323 || (index()[offset].rule & mask_)!=0;
328 return index().size();
331 index_type const &index() const
333 return map_->index();
338 std::pair<size_t,size_t> current_;
339 mapping_type const *map_;
344 template<typename BaseIterator>
345 class boundary_point_index_iterator :
346 public boost::iterator_facade<
347 boundary_point_index_iterator<BaseIterator>,
348 boundary_point<BaseIterator>,
349 boost::bidirectional_traversal_tag,
350 boundary_point<BaseIterator> const &
354 typedef BaseIterator base_iterator;
355 typedef mapping<base_iterator> mapping_type;
356 typedef boundary_point<base_iterator> boundary_point_type;
358 boundary_point_index_iterator() : current_(0),map_(0)
362 boundary_point_index_iterator(bool is_begin,mapping_type const *map,rule_type mask) :
371 boundary_point_index_iterator(base_iterator p,mapping_type const *map,rule_type mask) :
378 boundary_point_type const &dereference() const
383 bool equal(boundary_point_index_iterator const &other) const
385 return map_ == other.map_ && current_ == other.current_;
390 size_t next = current_;
391 while(next < size()) {
393 if(valid_offset(next))
396 update_current(next);
401 size_t next = current_;
404 if(valid_offset(next))
407 update_current(next);
414 value_ = boundary_point_type(map_->end(),0);
419 value_ = boundary_point_type(map_->begin(),0);
422 void set(base_iterator p)
424 size_t dist = std::distance(map_->begin(),p);
426 index_type::const_iterator b=index().begin();
427 index_type::const_iterator e=index().end();
428 index_type::const_iterator ptr = std::lower_bound(b,e,break_info(dist));
430 if(ptr==index().end())
433 current_=ptr - index().begin();
435 while(!valid_offset(current_))
438 std::ptrdiff_t diff = get_offset(current_) - dist;
439 std::advance(p,diff);
444 void update_current(size_t pos)
446 std::ptrdiff_t diff = get_offset(pos) - get_offset(current_);
447 base_iterator i=value_.iterator();
448 std::advance(i,diff);
456 if(current_ != size()) {
457 value_.rule(index()[current_].rule);
460 size_t get_offset(size_t ind) const
463 return index().back().offset;
464 return index()[ind].offset;
467 bool valid_offset(size_t offset) const
470 || offset + 1 >= size() // last and first are always valid regardless of mark
471 || (index()[offset].rule & mask_)!=0;
476 return index().size();
479 index_type const &index() const
481 return map_->index();
485 boundary_point_type value_;
487 mapping_type const *map_;
496 template<typename BaseIterator>
499 template<typename BaseIterator>
500 class boundary_point_index;
504 /// \brief This class holds an index of segments in the text range and allows to iterate over them
506 /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators
507 /// to the \ref segment objects.
509 /// It provides two options on way of selecting segments:
511 /// - \ref rule(rule_type mask) - a mask that allows to select only specific types of segments according to
512 /// various masks %as \ref word_any.
514 /// The default is to select any types of boundaries.
516 /// For example: using word %boundary analysis, when the provided mask is \ref word_kana then the iterators
517 /// would iterate only over the words containing Kana letters and \ref word_any would select all types of
518 /// words excluding ranges that consist of white space and punctuation marks. So iterating over the text
519 /// "to be or not to be?" with \ref word_any rule would return segments "to", "be", "or", "not", "to", "be", instead
520 /// of default "to", " ", "be", " ", "or", " ", "not", " ", "to", " ", "be", "?".
521 /// - \ref full_select(bool how) - a flag that defines the way a range is selected if the rule of the previous
522 /// %boundary point does not fit the selected rule.
524 /// For example: We want to fetch all sentences from the following text: "Hello! How\nare you?".
526 /// This text contains three %boundary points separating it to sentences by different rules:
527 /// - The exclamation mark "!" ends the sentence "Hello!"
528 /// - The line feed that splits the sentence "How\nare you?" into two parts.
529 /// - The question mark that ends the second sentence.
531 /// If you would only change the \ref rule() to \ref sentence_term then the segment_index would
532 /// provide two sentences "Hello!" and "are you?" %as only them actually terminated with required
533 /// terminator "!" or "?". But changing \ref full_select() to true, the selected segment would include
534 /// all the text up to previous valid %boundary point and would return two expected sentences:
535 /// "Hello!" and "How\nare you?".
537 /// This class allows to find a segment according to the given iterator in range using \ref find() member
542 /// - Changing any of the options - \ref rule() or \ref full_select() and of course re-indexing the text
543 /// invalidates existing iterators and they can't be used any more.
544 /// - segment_index can be created from boundary_point_index or other segment_index that was created with
545 /// same \ref boundary_type. This is very fast operation %as they shared same index
546 /// and it does not require its regeneration.
550 /// - \ref boundary_point_index
552 /// - \ref boundary_point
555 template<typename BaseIterator>
556 class segment_index {
560 /// The type of the iterator used to iterate over the original text
562 typedef BaseIterator base_iterator;
563 #ifdef BOOST_LOCALE_DOXYGEN
565 /// The bidirectional iterator that iterates over \ref value_type objects.
567 /// - The iterators may be invalidated by use of any non-const member function
568 /// including but not limited to \ref rule(rule_type) and \ref full_select(bool).
569 /// - The returned value_type object is valid %as long %as iterator points to it.
570 /// So this following code is wrong %as t used after p was updated:
572 /// segment_index<some_iterator>::iterator p=index.begin();
573 /// segment<some_iterator> &t = *p;
575 /// cout << t.str() << endl;
578 typedef unspecified_iterator_type iterator;
580 /// \copydoc iterator
582 typedef unspecified_iterator_type const_iterator;
584 typedef details::segment_index_iterator<base_iterator> iterator;
585 typedef details::segment_index_iterator<base_iterator> const_iterator;
588 /// The type dereferenced by the \ref iterator and \ref const_iterator. It is
589 /// an object that represents selected segment.
591 typedef segment<base_iterator> value_type;
594 /// Default constructor.
598 /// When this object is constructed by default it does not include a valid index, thus
599 /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined
602 segment_index() : mask_(0xFFFFFFFFu),full_select_(false)
606 /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text
607 /// in range [begin,end) using a rule \a mask for locale \a loc.
609 segment_index(boundary_type type,
613 std::locale const &loc=std::locale())
615 map_(type,begin,end,loc),
621 /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text
622 /// in range [begin,end) selecting all possible segments (full mask) for locale \a loc.
624 segment_index(boundary_type type,
627 std::locale const &loc=std::locale())
629 map_(type,begin,end,loc),
636 /// Create a segment_index from a \ref boundary_point_index. It copies all indexing information
637 /// and used default rule (all possible segments)
639 /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text
640 /// range it is much better to create one from another rather then indexing the same
643 /// \note \ref rule() flags are not copied
645 segment_index(boundary_point_index<base_iterator> const &);
647 /// Copy an index from a \ref boundary_point_index. It copies all indexing information
648 /// and uses the default rule (all possible segments)
650 /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text
651 /// range it is much better to create one from another rather then indexing the same
654 /// \note \ref rule() flags are not copied
656 segment_index const &operator = (boundary_point_index<base_iterator> const &);
660 /// Create a new index for %boundary analysis \ref boundary_type "type" of the text
661 /// in range [begin,end) for locale \a loc.
663 /// \note \ref rule() and \ref full_select() remain unchanged.
665 void map(boundary_type type,base_iterator begin,base_iterator end,std::locale const &loc=std::locale())
667 map_ = mapping_type(type,begin,end,loc);
671 /// Get the \ref iterator on the beginning of the segments range.
673 /// Preconditions: the segment_index should have a mapping
677 /// The returned iterator is invalidated by access to any non-const member functions of this object
679 iterator begin() const
681 return iterator(true,&map_,mask_,full_select_);
685 /// Get the \ref iterator on the ending of the segments range.
687 /// Preconditions: the segment_index should have a mapping
689 /// The returned iterator is invalidated by access to any non-const member functions of this object
693 return iterator(false,&map_,mask_,full_select_);
697 /// Find a first valid segment following a position \a p.
699 /// If \a p is inside a valid segment this segment is selected:
701 /// For example: For \ref word %boundary analysis with \ref word_any rule():
703 /// - "to| be or ", would point to "be",
704 /// - "t|o be or ", would point to "to",
705 /// - "to be or| ", would point to end.
708 /// Preconditions: the segment_index should have a mapping and \a p should be valid iterator
709 /// to the text in the mapped range.
711 /// The returned iterator is invalidated by access to any non-const member functions of this object
713 iterator find(base_iterator p) const
715 return iterator(p,&map_,mask_,full_select_);
719 /// Get the mask of rules that are used
721 rule_type rule() const
726 /// Set the mask of rules that are used
728 void rule(rule_type v)
734 /// Get the full_select property value - should segment include in the range
735 /// values that not belong to specific \ref rule() or not.
737 /// The default value is false.
739 /// For example for \ref sentence %boundary with rule \ref sentence_term the segments
740 /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false
741 /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select()
742 /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the
743 /// following part "are you?"
746 bool full_select() const
752 /// Set the full_select property value - should segment include in the range
753 /// values that not belong to specific \ref rule() or not.
755 /// The default value is false.
757 /// For example for \ref sentence %boundary with rule \ref sentence_term the segments
758 /// of text "Hello! How\nare you?" are "Hello!\", "are you?" when full_select() is false
759 /// because "How\n" is selected %as sentence by a rule spits the text by line feed. If full_select()
760 /// is true the returned segments are "Hello! ", "How\nare you?" where "How\n" is joined with the
761 /// following part "are you?"
764 void full_select(bool v)
770 friend class boundary_point_index<base_iterator>;
771 typedef details::mapping<base_iterator> mapping_type;
778 /// \brief This class holds an index of \ref boundary_point "boundary points" and allows iterating
781 /// This class is provides \ref begin() and \ref end() member functions that return bidirectional iterators
782 /// to the \ref boundary_point objects.
784 /// It provides an option that affects selecting %boundary points according to different rules:
785 /// using \ref rule(rule_type mask) member function. It allows to set a mask that select only specific
786 /// types of %boundary points like \ref sentence_term.
788 /// For example for a sentence %boundary analysis of a text "Hello! How\nare you?" when the default
789 /// rule is used the %boundary points would be:
791 /// - "|Hello! How\nare you?"
792 /// - "Hello! |How\nare you?"
793 /// - "Hello! How\n|are you?"
794 /// - "Hello! How\nare you?|"
796 /// However if \ref rule() is set to \ref sentence_term then the selected %boundary points would be:
798 /// - "|Hello! How\nare you?"
799 /// - "Hello! |How\nare you?"
800 /// - "Hello! How\nare you?|"
802 /// Such that a %boundary point defined by a line feed character would be ignored.
804 /// This class allows to find a boundary_point according to the given iterator in range using \ref find() member
808 /// - Even an empty text range [x,x) considered to have a one %boundary point x.
809 /// - \a a and \a b points of the range [a,b) are always considered %boundary points
810 /// regardless the rules used.
811 /// - Changing any of the option \ref rule() or course re-indexing the text
812 /// invalidates existing iterators and they can't be used any more.
813 /// - boundary_point_index can be created from segment_index or other boundary_point_index that was created with
814 /// same \ref boundary_type. This is very fast operation %as they shared same index
815 /// and it does not require its regeneration.
819 /// - \ref segment_index
820 /// - \ref boundary_point
825 template<typename BaseIterator>
826 class boundary_point_index {
829 /// The type of the iterator used to iterate over the original text
831 typedef BaseIterator base_iterator;
832 #ifdef BOOST_LOCALE_DOXYGEN
834 /// The bidirectional iterator that iterates over \ref value_type objects.
836 /// - The iterators may be invalidated by use of any non-const member function
837 /// including but not limited to \ref rule(rule_type) member function.
838 /// - The returned value_type object is valid %as long %as iterator points to it.
839 /// So this following code is wrong %as t used after p was updated:
841 /// boundary_point_index<some_iterator>::iterator p=index.begin();
842 /// boundary_point<some_iterator> &t = *p;
844 /// rule_type r = t->rule();
847 typedef unspecified_iterator_type iterator;
849 /// \copydoc iterator
851 typedef unspecified_iterator_type const_iterator;
853 typedef details::boundary_point_index_iterator<base_iterator> iterator;
854 typedef details::boundary_point_index_iterator<base_iterator> const_iterator;
857 /// The type dereferenced by the \ref iterator and \ref const_iterator. It is
858 /// an object that represents the selected \ref boundary_point "boundary point".
860 typedef boundary_point<base_iterator> value_type;
863 /// Default constructor.
867 /// When this object is constructed by default it does not include a valid index, thus
868 /// calling \ref begin(), \ref end() or \ref find() member functions would lead to undefined
871 boundary_point_index() : mask_(0xFFFFFFFFu)
876 /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text
877 /// in range [begin,end) using a rule \a mask for locale \a loc.
879 boundary_point_index(boundary_type type,
883 std::locale const &loc=std::locale())
885 map_(type,begin,end,loc),
890 /// Create a segment_index for %boundary analysis \ref boundary_type "type" of the text
891 /// in range [begin,end) selecting all possible %boundary points (full mask) for locale \a loc.
893 boundary_point_index(boundary_type type,
896 std::locale const &loc=std::locale())
898 map_(type,begin,end,loc),
904 /// Create a boundary_point_index from a \ref segment_index. It copies all indexing information
905 /// and uses the default rule (all possible %boundary points)
907 /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text
908 /// range it is much better to create one from another rather then indexing the same
911 /// \note \ref rule() flags are not copied
913 boundary_point_index(segment_index<base_iterator> const &other);
915 /// Copy a boundary_point_index from a \ref segment_index. It copies all indexing information
916 /// and keeps the current \ref rule() unchanged
918 /// This operation is very cheap, so if you use boundary_point_index and segment_index on same text
919 /// range it is much better to create one from another rather then indexing the same
922 /// \note \ref rule() flags are not copied
924 boundary_point_index const &operator=(segment_index<base_iterator> const &other);
927 /// Create a new index for %boundary analysis \ref boundary_type "type" of the text
928 /// in range [begin,end) for locale \a loc.
930 /// \note \ref rule() remains unchanged.
932 void map(boundary_type type,base_iterator begin,base_iterator end,std::locale const &loc=std::locale())
934 map_ = mapping_type(type,begin,end,loc);
938 /// Get the \ref iterator on the beginning of the %boundary points range.
940 /// Preconditions: this boundary_point_index should have a mapping
944 /// The returned iterator is invalidated by access to any non-const member functions of this object
946 iterator begin() const
948 return iterator(true,&map_,mask_);
952 /// Get the \ref iterator on the ending of the %boundary points range.
954 /// Preconditions: this boundary_point_index should have a mapping
958 /// The returned iterator is invalidated by access to any non-const member functions of this object
962 return iterator(false,&map_,mask_);
966 /// Find a first valid %boundary point on a position \a p or following it.
968 /// For example: For \ref word %boundary analysis of the text "to be or"
970 /// - "|to be", would return %boundary point at "|to be",
971 /// - "t|o be", would point to "to| be"
973 /// Preconditions: the boundary_point_index should have a mapping and \a p should be valid iterator
974 /// to the text in the mapped range.
976 /// The returned iterator is invalidated by access to any non-const member functions of this object
978 iterator find(base_iterator p) const
980 return iterator(p,&map_,mask_);
984 /// Get the mask of rules that are used
986 rule_type rule() const
991 /// Set the mask of rules that are used
993 void rule(rule_type v)
1000 friend class segment_index<base_iterator>;
1001 typedef details::mapping<base_iterator> mapping_type;
1007 template<typename BaseIterator>
1008 segment_index<BaseIterator>::segment_index(boundary_point_index<BaseIterator> const &other) :
1015 template<typename BaseIterator>
1016 boundary_point_index<BaseIterator>::boundary_point_index(segment_index<BaseIterator> const &other) :
1022 template<typename BaseIterator>
1023 segment_index<BaseIterator> const &segment_index<BaseIterator>::operator=(boundary_point_index<BaseIterator> const &other)
1029 template<typename BaseIterator>
1030 boundary_point_index<BaseIterator> const &boundary_point_index<BaseIterator>::operator=(segment_index<BaseIterator> const &other)
1037 typedef segment_index<std::string::const_iterator> ssegment_index; ///< convenience typedef
1038 typedef segment_index<std::wstring::const_iterator> wssegment_index; ///< convenience typedef
1039 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
1040 typedef segment_index<std::u16string::const_iterator> u16ssegment_index;///< convenience typedef
1042 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
1043 typedef segment_index<std::u32string::const_iterator> u32ssegment_index;///< convenience typedef
1046 typedef segment_index<char const *> csegment_index; ///< convenience typedef
1047 typedef segment_index<wchar_t const *> wcsegment_index; ///< convenience typedef
1048 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
1049 typedef segment_index<char16_t const *> u16csegment_index; ///< convenience typedef
1051 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
1052 typedef segment_index<char32_t const *> u32csegment_index; ///< convenience typedef
1055 typedef boundary_point_index<std::string::const_iterator> sboundary_point_index;///< convenience typedef
1056 typedef boundary_point_index<std::wstring::const_iterator> wsboundary_point_index;///< convenience typedef
1057 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
1058 typedef boundary_point_index<std::u16string::const_iterator> u16sboundary_point_index;///< convenience typedef
1060 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
1061 typedef boundary_point_index<std::u32string::const_iterator> u32sboundary_point_index;///< convenience typedef
1064 typedef boundary_point_index<char const *> cboundary_point_index; ///< convenience typedef
1065 typedef boundary_point_index<wchar_t const *> wcboundary_point_index; ///< convenience typedef
1066 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
1067 typedef boundary_point_index<char16_t const *> u16cboundary_point_index;///< convenience typedef
1069 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
1070 typedef boundary_point_index<char32_t const *> u32cboundary_point_index;///< convenience typedef
1081 /// \example boundary.cpp
1082 /// Example of using segment_index
1083 /// \example wboundary.cpp
1084 /// Example of using segment_index over wide strings
1088 #pragma warning(pop)
1092 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4