Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:07

0001 /*
0002    Copyright (c) Marshall Clow 2012-2015.
0003    Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
0004 
0005    Distributed under the Boost Software License, Version 1.0. (See accompanying
0006    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008     For more information, see http://www.boost.org
0009 
0010     Based on the StringRef implementation in LLVM (http://llvm.org) and
0011     N3422 by Jeffrey Yasskin
0012         http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
0013 
0014 */
0015 
0016 #ifndef BOOST_STRING_REF_HPP
0017 #define BOOST_STRING_REF_HPP
0018 
0019 #include <boost/config.hpp>
0020 #include <boost/detail/workaround.hpp>
0021 #include <boost/io/ostream_put.hpp>
0022 #include <boost/utility/string_ref_fwd.hpp>
0023 #include <boost/throw_exception.hpp>
0024 
0025 #include <cstddef>
0026 #include <stdexcept>
0027 #include <algorithm>
0028 #include <iterator>
0029 #include <string>
0030 #include <iosfwd>
0031 
0032 #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
0033 // GCC 4.6 cannot handle a defaulted function with noexcept specifier
0034 #define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
0035 #endif
0036 
0037 namespace boost {
0038 
0039     namespace detail {
0040     //  A helper functor because sometimes we don't have lambdas
0041         template <typename charT, typename traits>
0042         class string_ref_traits_eq {
0043         public:
0044             string_ref_traits_eq ( charT ch ) : ch_(ch) {}
0045             bool operator () ( charT val ) const { return traits::eq ( ch_, val ); }
0046             charT ch_;
0047             };
0048         }
0049 
0050     template<typename charT, typename traits>
0051     class basic_string_ref {
0052     public:
0053         // types
0054         typedef charT value_type;
0055         typedef const charT* pointer;
0056         typedef const charT& reference;
0057         typedef const charT& const_reference;
0058         typedef pointer const_iterator; // impl-defined
0059         typedef const_iterator iterator;
0060         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0061         typedef const_reverse_iterator reverse_iterator;
0062         typedef std::size_t size_type;
0063         typedef std::ptrdiff_t difference_type;
0064         static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
0065 
0066         // construct/copy
0067         BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT
0068             : ptr_(NULL), len_(0) {}
0069 
0070         // by defaulting these functions, basic_string_ref becomes
0071         //  trivially copy/move constructible.
0072         BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) BOOST_NOEXCEPT
0073 #ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
0074             = default;
0075 #else
0076             : ptr_(rhs.ptr_), len_(rhs.len_) {}
0077 #endif
0078 
0079         basic_string_ref& operator=(const basic_string_ref &rhs) BOOST_NOEXCEPT
0080 #ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
0081             = default;
0082 #else
0083             {
0084             ptr_ = rhs.ptr_;
0085             len_ = rhs.len_;
0086             return *this;
0087             }
0088 #endif
0089 
0090         basic_string_ref(const charT* str) BOOST_NOEXCEPT
0091             : ptr_(str), len_(traits::length(str)) {}
0092 
0093         template<typename Allocator>
0094         basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
0095             : ptr_(str.data()), len_(str.length()) {}
0096 
0097 // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
0098 //         // Constructing a string_ref from a temporary string is a bad idea
0099 //         template<typename Allocator>
0100 //         basic_string_ref(      std::basic_string<charT, traits, Allocator>&&)
0101 //             = delete;
0102 // #endif
0103 
0104         BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT
0105             : ptr_(str), len_(len) {}
0106 
0107 #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
0108         template<typename Allocator>
0109         explicit operator std::basic_string<charT, traits, Allocator>() const {
0110             return std::basic_string<charT, traits, Allocator> ( begin(), end());
0111             }
0112 #endif
0113 
0114         std::basic_string<charT, traits> to_string () const {
0115             return std::basic_string<charT, traits> ( begin(), end());
0116             }
0117 
0118         // iterators
0119         BOOST_CONSTEXPR const_iterator   begin() const { return ptr_; }
0120         BOOST_CONSTEXPR const_iterator  cbegin() const { return ptr_; }
0121         BOOST_CONSTEXPR const_iterator     end() const { return ptr_ + len_; }
0122         BOOST_CONSTEXPR const_iterator    cend() const { return ptr_ + len_; }
0123                 const_reverse_iterator  rbegin() const { return const_reverse_iterator (end()); }
0124                 const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); }
0125                 const_reverse_iterator    rend() const { return const_reverse_iterator (begin()); }
0126                 const_reverse_iterator   crend() const { return const_reverse_iterator (begin()); }
0127 
0128         // capacity
0129         BOOST_CONSTEXPR size_type size()     const { return len_; }
0130         BOOST_CONSTEXPR size_type length()   const { return len_; }
0131         BOOST_CONSTEXPR size_type max_size() const { return ~static_cast<size_type>(0) / (sizeof(value_type) * 2u); }
0132         BOOST_CONSTEXPR bool empty()         const { return len_ == 0; }
0133 
0134         // element access
0135         BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; }
0136 
0137         const charT& at(size_type pos) const {
0138             if ( pos >= len_ )
0139                 BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) );
0140             return ptr_[pos];
0141             }
0142 
0143         BOOST_CONSTEXPR const charT& front() const { return ptr_[0]; }
0144         BOOST_CONSTEXPR const charT& back()  const { return ptr_[len_-1]; }
0145         BOOST_CONSTEXPR const charT* data()  const { return ptr_; }
0146 
0147         // modifiers
0148         void clear() { len_ = 0; }
0149         void remove_prefix(size_type n) {
0150             if ( n > len_ )
0151                 n = len_;
0152             ptr_ += n;
0153             len_ -= n;
0154             }
0155 
0156         void remove_suffix(size_type n) {
0157             if ( n > len_ )
0158                 n = len_;
0159             len_ -= n;
0160             }
0161 
0162 
0163         // basic_string_ref string operations
0164         basic_string_ref substr() const {
0165             return basic_string_ref(data(), size());
0166             }
0167 
0168         basic_string_ref substr(size_type pos, size_type n=npos) const {
0169             if ( pos > size())
0170                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
0171             return basic_string_ref(data() + pos, (std::min)(size() - pos, n));
0172             }
0173 
0174         int compare(basic_string_ref x) const {
0175             const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_));
0176             return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 );
0177             }
0178 
0179         bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); }
0180         bool starts_with(basic_string_ref x) const {
0181             return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
0182             }
0183 
0184         bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); }
0185         bool ends_with(basic_string_ref x) const {
0186             return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0;
0187             }
0188 
0189         size_type find(basic_string_ref s) const {
0190             if (s.empty()) return 0;
0191             const_iterator iter = std::search ( this->cbegin (), this->cend (),
0192                                                 s.cbegin (), s.cend (), traits::eq );
0193             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
0194             }
0195 
0196         size_type find(charT c) const {
0197             const_iterator iter = std::find_if ( this->cbegin (), this->cend (),
0198                                     detail::string_ref_traits_eq<charT, traits> ( c ));
0199             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
0200             }
0201 
0202         size_type rfind(basic_string_ref s) const {
0203             if (s.empty()) return 0;
0204             const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
0205                                                 s.crbegin (), s.crend (), traits::eq );
0206             return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size());
0207             }
0208 
0209         size_type rfind(charT c) const {
0210             const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
0211                                     detail::string_ref_traits_eq<charT, traits> ( c ));
0212             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
0213             }
0214 
0215         size_type find_first_of(charT c) const { return  find (c); }
0216         size_type find_last_of (charT c) const { return rfind (c); }
0217 
0218         size_type find_first_of(basic_string_ref s) const {
0219             const_iterator iter = std::find_first_of
0220                 ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
0221             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
0222             }
0223 
0224         size_type find_last_of(basic_string_ref s) const {
0225             const_reverse_iterator iter = std::find_first_of
0226                 ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
0227             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
0228             }
0229 
0230         size_type find_first_not_of(basic_string_ref s) const {
0231             const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
0232             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
0233             }
0234 
0235         size_type find_first_not_of(charT c) const {
0236             for ( const_iterator iter = this->cbegin (); iter != this->cend (); ++iter )
0237                 if ( !traits::eq ( c, *iter ))
0238                     return std::distance ( this->cbegin (), iter );
0239             return npos;
0240             }
0241 
0242         size_type find_last_not_of(basic_string_ref s) const {
0243             const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
0244             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
0245             }
0246 
0247         size_type find_last_not_of(charT c) const {
0248             for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
0249                 if ( !traits::eq ( c, *iter ))
0250                     return this->size() - 1 - std::distance(this->crbegin(), iter);
0251             return npos;
0252             }
0253 
0254     private:
0255 
0256         template <typename Iterator>
0257         Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
0258             for ( ; first != last ; ++first )
0259                 if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
0260                     return first;
0261             return last;
0262             }
0263 
0264 
0265 
0266         const charT *ptr_;
0267         std::size_t len_;
0268         };
0269 
0270 
0271 //  Comparison operators
0272 //  Equality
0273     template<typename charT, typename traits>
0274     inline bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0275         if ( x.size () != y.size ()) return false;
0276         return x.compare(y) == 0;
0277         }
0278 
0279     template<typename charT, typename traits, typename Allocator>
0280     inline bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0281         return x == basic_string_ref<charT, traits>(y);
0282         }
0283 
0284     template<typename charT, typename traits, typename Allocator>
0285     inline bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0286         return basic_string_ref<charT, traits>(x) == y;
0287         }
0288 
0289     template<typename charT, typename traits>
0290     inline bool operator==(basic_string_ref<charT, traits> x, const charT * y) {
0291         return x == basic_string_ref<charT, traits>(y);
0292         }
0293 
0294     template<typename charT, typename traits>
0295     inline bool operator==(const charT * x, basic_string_ref<charT, traits> y) {
0296         return basic_string_ref<charT, traits>(x) == y;
0297         }
0298 
0299 //  Inequality
0300     template<typename charT, typename traits>
0301     inline bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0302         if ( x.size () != y.size ()) return true;
0303         return x.compare(y) != 0;
0304         }
0305 
0306     template<typename charT, typename traits, typename Allocator>
0307     inline bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0308         return x != basic_string_ref<charT, traits>(y);
0309         }
0310 
0311     template<typename charT, typename traits, typename Allocator>
0312     inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0313         return basic_string_ref<charT, traits>(x) != y;
0314         }
0315 
0316     template<typename charT, typename traits>
0317     inline bool operator!=(basic_string_ref<charT, traits> x, const charT * y) {
0318         return x != basic_string_ref<charT, traits>(y);
0319         }
0320 
0321     template<typename charT, typename traits>
0322     inline bool operator!=(const charT * x, basic_string_ref<charT, traits> y) {
0323         return basic_string_ref<charT, traits>(x) != y;
0324         }
0325 
0326 //  Less than
0327     template<typename charT, typename traits>
0328     inline bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0329         return x.compare(y) < 0;
0330         }
0331 
0332     template<typename charT, typename traits, typename Allocator>
0333     inline bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0334         return x < basic_string_ref<charT, traits>(y);
0335         }
0336 
0337     template<typename charT, typename traits, typename Allocator>
0338     inline bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0339         return basic_string_ref<charT, traits>(x) < y;
0340         }
0341 
0342     template<typename charT, typename traits>
0343     inline bool operator<(basic_string_ref<charT, traits> x, const charT * y) {
0344         return x < basic_string_ref<charT, traits>(y);
0345         }
0346 
0347     template<typename charT, typename traits>
0348     inline bool operator<(const charT * x, basic_string_ref<charT, traits> y) {
0349         return basic_string_ref<charT, traits>(x) < y;
0350         }
0351 
0352 //  Greater than
0353     template<typename charT, typename traits>
0354     inline bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0355         return x.compare(y) > 0;
0356         }
0357 
0358     template<typename charT, typename traits, typename Allocator>
0359     inline bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0360         return x > basic_string_ref<charT, traits>(y);
0361         }
0362 
0363     template<typename charT, typename traits, typename Allocator>
0364     inline bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0365         return basic_string_ref<charT, traits>(x) > y;
0366         }
0367 
0368     template<typename charT, typename traits>
0369     inline bool operator>(basic_string_ref<charT, traits> x, const charT * y) {
0370         return x > basic_string_ref<charT, traits>(y);
0371         }
0372 
0373     template<typename charT, typename traits>
0374     inline bool operator>(const charT * x, basic_string_ref<charT, traits> y) {
0375         return basic_string_ref<charT, traits>(x) > y;
0376         }
0377 
0378 //  Less than or equal to
0379     template<typename charT, typename traits>
0380     inline bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0381         return x.compare(y) <= 0;
0382         }
0383 
0384     template<typename charT, typename traits, typename Allocator>
0385     inline bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0386         return x <= basic_string_ref<charT, traits>(y);
0387         }
0388 
0389     template<typename charT, typename traits, typename Allocator>
0390     inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0391         return basic_string_ref<charT, traits>(x) <= y;
0392         }
0393 
0394     template<typename charT, typename traits>
0395     inline bool operator<=(basic_string_ref<charT, traits> x, const charT * y) {
0396         return x <= basic_string_ref<charT, traits>(y);
0397         }
0398 
0399     template<typename charT, typename traits>
0400     inline bool operator<=(const charT * x, basic_string_ref<charT, traits> y) {
0401         return basic_string_ref<charT, traits>(x) <= y;
0402         }
0403 
0404 //  Greater than or equal to
0405     template<typename charT, typename traits>
0406     inline bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
0407         return x.compare(y) >= 0;
0408         }
0409 
0410     template<typename charT, typename traits, typename Allocator>
0411     inline bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
0412         return x >= basic_string_ref<charT, traits>(y);
0413         }
0414 
0415     template<typename charT, typename traits, typename Allocator>
0416     inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
0417         return basic_string_ref<charT, traits>(x) >= y;
0418         }
0419 
0420     template<typename charT, typename traits>
0421     inline bool operator>=(basic_string_ref<charT, traits> x, const charT * y) {
0422         return x >= basic_string_ref<charT, traits>(y);
0423         }
0424 
0425     template<typename charT, typename traits>
0426     inline bool operator>=(const charT * x, basic_string_ref<charT, traits> y) {
0427         return basic_string_ref<charT, traits>(x) >= y;
0428         }
0429 
0430     // Inserter
0431     template<class charT, class traits>
0432     inline std::basic_ostream<charT, traits>&
0433     operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
0434         return boost::io::ostream_put(os, str.data(), str.size());
0435         }
0436 
0437 #if 0
0438     // numeric conversions
0439     //
0440     //  These are short-term implementations.
0441     //  In a production environment, I would rather avoid the copying.
0442     //
0443     inline int stoi (string_ref str, size_t* idx=0, int base=10) {
0444         return std::stoi ( std::string(str), idx, base );
0445         }
0446 
0447     inline long stol (string_ref str, size_t* idx=0, int base=10) {
0448         return std::stol ( std::string(str), idx, base );
0449         }
0450 
0451     inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
0452         return std::stoul ( std::string(str), idx, base );
0453         }
0454 
0455     inline long long stoll (string_ref str, size_t* idx=0, int base=10) {
0456         return std::stoll ( std::string(str), idx, base );
0457         }
0458 
0459     inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
0460         return std::stoull ( std::string(str), idx, base );
0461         }
0462 
0463     inline float stof (string_ref str, size_t* idx=0) {
0464         return std::stof ( std::string(str), idx );
0465         }
0466 
0467     inline double stod (string_ref str, size_t* idx=0) {
0468         return std::stod ( std::string(str), idx );
0469         }
0470 
0471     inline long double stold (string_ref str, size_t* idx=0)  {
0472         return std::stold ( std::string(str), idx );
0473         }
0474 
0475     inline int  stoi (wstring_ref str, size_t* idx=0, int base=10) {
0476         return std::stoi ( std::wstring(str), idx, base );
0477         }
0478 
0479     inline long stol (wstring_ref str, size_t* idx=0, int base=10) {
0480         return std::stol ( std::wstring(str), idx, base );
0481         }
0482 
0483     inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
0484         return std::stoul ( std::wstring(str), idx, base );
0485         }
0486 
0487     inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
0488         return std::stoll ( std::wstring(str), idx, base );
0489         }
0490 
0491     inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
0492         return std::stoull ( std::wstring(str), idx, base );
0493         }
0494 
0495     inline float  stof (wstring_ref str, size_t* idx=0) {
0496         return std::stof ( std::wstring(str), idx );
0497         }
0498 
0499     inline double stod (wstring_ref str, size_t* idx=0) {
0500         return std::stod ( std::wstring(str), idx );
0501         }
0502 
0503     inline long double stold (wstring_ref str, size_t* idx=0) {
0504         return std::stold ( std::wstring(str), idx );
0505         }
0506 #endif
0507 
0508 }
0509 
0510 #if 0
0511 namespace std {
0512     // Hashing
0513     template<> struct hash<boost::string_ref>;
0514     template<> struct hash<boost::u16string_ref>;
0515     template<> struct hash<boost::u32string_ref>;
0516     template<> struct hash<boost::wstring_ref>;
0517 }
0518 #endif
0519 
0520 #endif