Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:56

0001 //
0002 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // https://www.boost.org/LICENSE_1_0.txt
0006 
0007 #ifndef BOOST_LOCALE_BOUNDARY_SEGMENT_HPP_INCLUDED
0008 #define BOOST_LOCALE_BOUNDARY_SEGMENT_HPP_INCLUDED
0009 
0010 #include <boost/locale/util/string.hpp>
0011 #include <iosfwd>
0012 #include <iterator>
0013 #include <locale>
0014 #include <string>
0015 
0016 #ifdef BOOST_MSVC
0017 #    pragma warning(push)
0018 #    pragma warning(disable : 4275 4251 4231 4660)
0019 #endif
0020 
0021 namespace boost { namespace locale { namespace boundary {
0022     /// \cond INTERNAL
0023     namespace detail {
0024         template<typename LeftIterator, typename RightIterator>
0025         int compare_text(LeftIterator l_begin, LeftIterator l_end, RightIterator r_begin, RightIterator r_end)
0026         {
0027             typedef LeftIterator left_iterator;
0028             typedef typename std::iterator_traits<left_iterator>::value_type char_type;
0029             typedef std::char_traits<char_type> traits;
0030             while(l_begin != l_end && r_begin != r_end) {
0031                 char_type lchar = *l_begin++;
0032                 char_type rchar = *r_begin++;
0033                 if(traits::eq(lchar, rchar))
0034                     continue;
0035                 if(traits::lt(lchar, rchar))
0036                     return -1;
0037                 else
0038                     return 1;
0039             }
0040             if(l_begin == l_end && r_begin == r_end)
0041                 return 0;
0042             if(l_begin == l_end)
0043                 return -1;
0044             else
0045                 return 1;
0046         }
0047 
0048         template<typename Left, typename Right>
0049         int compare_text(const Left& l, const Right& r)
0050         {
0051             return compare_text(l.begin(), l.end(), r.begin(), r.end());
0052         }
0053 
0054         template<typename Left, typename Char>
0055         int compare_string(const Left& l, const Char* begin)
0056         {
0057             return compare_text(l.begin(), l.end(), begin, util::str_end(begin));
0058         }
0059 
0060         template<typename Right, typename Char>
0061         int compare_string(const Char* begin, const Right& r)
0062         {
0063             return compare_text(begin, util::str_end(begin), r.begin(), r.end());
0064         }
0065 
0066     } // namespace detail
0067     /// \endcond
0068 
0069     /// \addtogroup boundary
0070     /// @{
0071 
0072     /// \brief a segment object that represents a pair of two iterators that define the range where
0073     /// this segment exits and a rule that defines it.
0074     ///
0075     /// This type of object is dereferenced by the iterators of segment_index. Using a rule() member function
0076     /// you can get a specific rule this segment was selected with. For example, when you use
0077     /// word boundary analysis, you can check if the specific word contains Kana letters by checking (rule() & \ref
0078     /// word_kana)!=0 For a sentence analysis you can check if the sentence is selected because a sentence terminator is
0079     /// found (\ref sentence_term) or there is a line break (\ref sentence_sep).
0080     ///
0081     /// This object can be automatically converted to std::basic_string with the same type of character. It is also
0082     /// valid range that has begin() and end() member functions returning iterators on the location of the segment.
0083     ///
0084     /// \see
0085     ///
0086     /// - \ref segment_index
0087     /// - \ref boundary_point
0088     /// - \ref boundary_point_index
0089     template<typename IteratorType>
0090     class segment : public std::pair<IteratorType, IteratorType> {
0091     public:
0092         /// The type of the underlying character
0093         typedef typename std::iterator_traits<IteratorType>::value_type char_type;
0094         /// The type of the string it is converted to
0095         typedef std::basic_string<char_type> string_type;
0096         /// The value that iterators return  - the character itself
0097         typedef char_type value_type;
0098         /// The iterator that allows to iterate the range
0099         typedef IteratorType iterator;
0100         /// The iterator that allows to iterate the range
0101         typedef IteratorType const_iterator;
0102         /// The type that represent a difference between two iterators
0103         typedef typename std::iterator_traits<IteratorType>::difference_type difference_type;
0104 
0105         /// Default constructor
0106         segment() : rule_(0) {}
0107         /// Create a segment using two iterators and a rule that represents this point
0108         segment(iterator b, iterator e, rule_type r) : std::pair<IteratorType, IteratorType>(b, e), rule_(r) {}
0109         /// Set the start of the range
0110         void begin(const iterator& v) { this->first = v; }
0111         /// Set the end of the range
0112         void end(const iterator& v) { this->second = v; }
0113 
0114         /// Get the start of the range
0115         IteratorType begin() const { return this->first; }
0116         /// Set the end of the range
0117         IteratorType end() const { return this->second; }
0118 
0119         /// Convert the range to a string automatically
0120         template<class T, class A>
0121         operator std::basic_string<char_type, T, A>() const
0122         {
0123             return std::basic_string<char_type, T, A>(this->first, this->second);
0124         }
0125 
0126         /// Create a string from the range explicitly
0127         string_type str() const { return string_type(begin(), end()); }
0128 
0129         /// Get the length of the text chunk
0130         size_t length() const { return std::distance(begin(), end()); }
0131 
0132         /// Check if the segment is empty
0133         bool empty() const { return begin() == end(); }
0134 
0135         /// Get the rule that is used for selection of this segment.
0136         rule_type rule() const { return rule_; }
0137         /// Set a rule that is used for segment selection
0138         void rule(rule_type r) { rule_ = r; }
0139 
0140         // make sure we override std::pair's operator==
0141 
0142         /// Compare two segments
0143         bool operator==(const segment& other) const { return detail::compare_text(*this, other) == 0; }
0144         /// Compare two segments
0145         bool operator!=(const segment& other) const { return detail::compare_text(*this, other) != 0; }
0146 
0147     private:
0148         rule_type rule_;
0149     };
0150 
0151     /// Compare two segments
0152     template<typename IteratorL, typename IteratorR>
0153     bool operator==(const segment<IteratorL>& l, const segment<IteratorR>& r)
0154     {
0155         return detail::compare_text(l, r) == 0;
0156     }
0157     /// Compare two segments
0158     template<typename IteratorL, typename IteratorR>
0159     bool operator!=(const segment<IteratorL>& l, const segment<IteratorR>& r)
0160     {
0161         return detail::compare_text(l, r) != 0;
0162     }
0163 
0164     /// Compare two segments
0165     template<typename IteratorL, typename IteratorR>
0166     bool operator<(const segment<IteratorL>& l, const segment<IteratorR>& r)
0167     {
0168         return detail::compare_text(l, r) < 0;
0169     }
0170     /// Compare two segments
0171     template<typename IteratorL, typename IteratorR>
0172     bool operator<=(const segment<IteratorL>& l, const segment<IteratorR>& r)
0173     {
0174         return detail::compare_text(l, r) <= 0;
0175     }
0176     /// Compare two segments
0177     template<typename IteratorL, typename IteratorR>
0178     bool operator>(const segment<IteratorL>& l, const segment<IteratorR>& r)
0179     {
0180         return detail::compare_text(l, r) > 0;
0181     }
0182     /// Compare two segments
0183     template<typename IteratorL, typename IteratorR>
0184     bool operator>=(const segment<IteratorL>& l, const segment<IteratorR>& r)
0185     {
0186         return detail::compare_text(l, r) >= 0;
0187     }
0188 
0189     /// Compare string and segment
0190     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0191     bool operator==(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0192     {
0193         return detail::compare_text(l, r) == 0;
0194     }
0195     /// Compare string and segment
0196     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0197     bool operator!=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0198     {
0199         return detail::compare_text(l, r) != 0;
0200     }
0201 
0202     /// Compare string and segment
0203     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0204     bool operator<(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0205     {
0206         return detail::compare_text(l, r) < 0;
0207     }
0208     /// Compare string and segment
0209     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0210     bool operator<=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0211     {
0212         return detail::compare_text(l, r) <= 0;
0213     }
0214     /// Compare string and segment
0215     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0216     bool operator>(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0217     {
0218         return detail::compare_text(l, r) > 0;
0219     }
0220     /// Compare string and segment
0221     template<typename CharType, typename Traits, typename Alloc, typename IteratorR>
0222     bool operator>=(const std::basic_string<CharType, Traits, Alloc>& l, const segment<IteratorR>& r)
0223     {
0224         return detail::compare_text(l, r) >= 0;
0225     }
0226 
0227     /// Compare string and segment
0228     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0229     bool operator==(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0230     {
0231         return detail::compare_text(l, r) == 0;
0232     }
0233     /// Compare string and segment
0234     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0235     bool operator!=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0236     {
0237         return detail::compare_text(l, r) != 0;
0238     }
0239 
0240     /// Compare string and segment
0241     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0242     bool operator<(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0243     {
0244         return detail::compare_text(l, r) < 0;
0245     }
0246     /// Compare string and segment
0247     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0248     bool operator<=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0249     {
0250         return detail::compare_text(l, r) <= 0;
0251     }
0252     /// Compare string and segment
0253     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0254     bool operator>(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0255     {
0256         return detail::compare_text(l, r) > 0;
0257     }
0258     /// Compare string and segment
0259     template<typename Iterator, typename CharType, typename Traits, typename Alloc>
0260     bool operator>=(const segment<Iterator>& l, const std::basic_string<CharType, Traits, Alloc>& r)
0261     {
0262         return detail::compare_text(l, r) >= 0;
0263     }
0264 
0265     /// Compare C string and segment
0266     template<typename CharType, typename IteratorR>
0267     bool operator==(const CharType* l, const segment<IteratorR>& r)
0268     {
0269         return detail::compare_string(l, r) == 0;
0270     }
0271     /// Compare C string and segment
0272     template<typename CharType, typename IteratorR>
0273     bool operator!=(const CharType* l, const segment<IteratorR>& r)
0274     {
0275         return detail::compare_string(l, r) != 0;
0276     }
0277 
0278     /// Compare C string and segment
0279     template<typename CharType, typename IteratorR>
0280     bool operator<(const CharType* l, const segment<IteratorR>& r)
0281     {
0282         return detail::compare_string(l, r) < 0;
0283     }
0284     /// Compare C string and segment
0285     template<typename CharType, typename IteratorR>
0286     bool operator<=(const CharType* l, const segment<IteratorR>& r)
0287     {
0288         return detail::compare_string(l, r) <= 0;
0289     }
0290     /// Compare C string and segment
0291     template<typename CharType, typename IteratorR>
0292     bool operator>(const CharType* l, const segment<IteratorR>& r)
0293     {
0294         return detail::compare_string(l, r) > 0;
0295     }
0296     /// Compare C string and segment
0297     template<typename CharType, typename IteratorR>
0298     bool operator>=(const CharType* l, const segment<IteratorR>& r)
0299     {
0300         return detail::compare_string(l, r) >= 0;
0301     }
0302 
0303     /// Compare C string and segment
0304     template<typename Iterator, typename CharType>
0305     bool operator==(const segment<Iterator>& l, const CharType* r)
0306     {
0307         return detail::compare_string(l, r) == 0;
0308     }
0309     /// Compare C string and segment
0310     template<typename Iterator, typename CharType>
0311     bool operator!=(const segment<Iterator>& l, const CharType* r)
0312     {
0313         return detail::compare_string(l, r) != 0;
0314     }
0315 
0316     /// Compare C string and segment
0317     template<typename Iterator, typename CharType>
0318     bool operator<(const segment<Iterator>& l, const CharType* r)
0319     {
0320         return detail::compare_string(l, r) < 0;
0321     }
0322     /// Compare C string and segment
0323     template<typename Iterator, typename CharType>
0324     bool operator<=(const segment<Iterator>& l, const CharType* r)
0325     {
0326         return detail::compare_string(l, r) <= 0;
0327     }
0328     /// Compare C string and segment
0329     template<typename Iterator, typename CharType>
0330     bool operator>(const segment<Iterator>& l, const CharType* r)
0331     {
0332         return detail::compare_string(l, r) > 0;
0333     }
0334     /// Compare C string and segment
0335     template<typename Iterator, typename CharType>
0336     bool operator>=(const segment<Iterator>& l, const CharType* r)
0337     {
0338         return detail::compare_string(l, r) >= 0;
0339     }
0340 
0341     typedef segment<std::string::const_iterator> ssegment;   ///< convenience typedef
0342     typedef segment<std::wstring::const_iterator> wssegment; ///< convenience typedef
0343 #ifndef BOOST_LOCALE_NO_CXX20_STRING8
0344     typedef segment<std::u8string::const_iterator> u8ssegment; ///< convenience typedef
0345 #endif
0346 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
0347     typedef segment<std::u16string::const_iterator> u16ssegment; ///< convenience typedef
0348 #endif
0349 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
0350     typedef segment<std::u32string::const_iterator> u32ssegment; ///< convenience typedef
0351 #endif
0352 
0353     typedef segment<const char*> csegment;     ///< convenience typedef
0354     typedef segment<const wchar_t*> wcsegment; ///< convenience typedef
0355 #ifdef __cpp_char8_t
0356     typedef segment<const char8_t*> u8csegment; ///< convenience typedef
0357 #endif
0358 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
0359     typedef segment<const char16_t*> u16csegment; ///< convenience typedef
0360 #endif
0361 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
0362     typedef segment<const char32_t*> u32csegment; ///< convenience typedef
0363 #endif
0364 
0365     /// Write the segment to the stream character by character
0366     template<typename CharType, typename TraitsType, typename Iterator>
0367     std::basic_ostream<CharType, TraitsType>& operator<<(std::basic_ostream<CharType, TraitsType>& out,
0368                                                          const segment<Iterator>& seg)
0369     {
0370         for(const auto& p : seg)
0371             out << p;
0372         return out;
0373     }
0374 
0375     /// @}
0376 
0377 }}} // namespace boost::locale::boundary
0378 
0379 #ifdef BOOST_MSVC
0380 #    pragma warning(pop)
0381 #endif
0382 
0383 #endif