zhangsongcui

basic_string_ref (unfinished)

Mar 10th, 2012
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.97 KB | None | 0 0
  1. #include <cassert>
  2. #include <string>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <stdexcept>
  6.  
  7. namespace std {
  8.     template<typename charT, typename traits = char_traits<charT>>
  9.     class basic_string_ref {
  10.     public:
  11.         // types
  12.         typedef charT value_type;
  13.         typedef const charT * pointer;
  14.         typedef const charT & reference;
  15.         typedef const charT & const_reference;
  16.         typedef const charT * const_iterator;
  17.         typedef const_iterator iterator;
  18.         typedef ::std::reverse_iterator< const_iterator > const_reverse_iterator;
  19.         typedef const_reverse_iterator reverse_iterator;
  20.         typedef size_t size_type;
  21.         typedef ptrdiff_t difference_type;
  22.         static constexpr size_type npos = size_type(-1);
  23.  
  24.         // construct/copy
  25.         constexpr basic_string_ref(): beg_(""), end_(beg_) {}
  26.         constexpr basic_string_ref(const basic_string_ref &rhs): beg_(rhs.beg_), end_(rhs.end_) {}
  27.         basic_string_ref & operator=(const basic_string_ref &rhs) { this->beg_= rhs.beg_; this->end_ = rhs.end_; }
  28.         basic_string_ref(const charT * str): beg_(str), end_(beg_ + ::std::strlen(str)) {}
  29.         template<typename Allocator>
  30.         basic_string_ref(const basic_string< charT, traits, Allocator > & str): beg_(&*str.begin()), end_(beg_ + str.size()) {}
  31.         constexpr basic_string_ref(const charT * str, size_type len): beg_(str), end_(beg_ + len) {}
  32.  
  33.         // iterators
  34.         constexpr const_iterator begin() const { return beg_; }
  35.         constexpr const_iterator end() const { return end_; }
  36.         constexpr const_iterator cbegin() const { return beg_; }
  37.         constexpr const_iterator cend() const { return end_; }
  38.         const_reverse_iterator rbegin() const { return end_; }
  39.         const_reverse_iterator rend() const { return beg_; }
  40.         const_reverse_iterator crbegin() const { return end_; }
  41.         const_reverse_iterator crend() const { return beg_; }
  42.  
  43.         // capacity
  44.         constexpr size_type size() const { return  end_ - beg_; }
  45.         constexpr size_type max_size() const { return this->size(); }
  46.         constexpr bool empty() const { return beg_ == end_; }
  47.         constexpr size_type length() const { return this->size(); }
  48.  
  49.         // element access
  50.         constexpr const charT & operator[](size_t i) const {
  51.             assert(i < this->size());
  52.             return beg_[i];
  53.         }
  54.         const charT & at(size_t i) const {
  55.             if (i >= this->size())
  56.                 throw ::std::length_error("basic_string_ref::at");
  57.             return beg_[i];
  58.         }
  59.         constexpr const charT & front() const { return beg_[0]; }
  60.         constexpr const charT & back() const { return end_[-1]; }
  61.         constexpr const charT * data() const { return beg_; }
  62.  
  63.         // Outgoing conversion operators
  64.         // constexpr operator array_ref< const charT >() const;
  65.         template<typename Allocator>
  66.         explicit operator basic_string< charT, traits, Allocator >() const { return basic_string< charT, traits >(begin(), end()); }
  67.         basic_string< charT, traits > str() const { return basic_string< charT, traits >(*this); }
  68.  
  69.         // mutators
  70.         void clear() { beg_ = end_ = ""; }
  71.         void remove_prefix(size_type n) { beg_ += n; assert(beg_ <= end_); }
  72.         void remove_suffix(size_type n) { end_ -= n; assert(end_ >= beg_); }
  73.         void pop_back() { this->remove_prefix(1); }
  74.         void pop_front() { this->remove_suffix(1); }
  75.  
  76.         // string operations with the same semantics as ::std::basic_string
  77.         int compare(basic_string_ref x) const {
  78.             return traits::compare(this->begin(), this->end(), ::std::min(this->size(), x.size()) + 1);
  79.             // return ::std::lexicographical_compare(this->begin(), this->end(), x.begin(), x.end());
  80.         }
  81.         constexpr basic_string_ref substr(size_type pos, size_type n=npos) const {
  82.             return basic_string_ref(this->begin() + pos, pos + n <= this->size() ? this->begin() + pos + n : this->end());
  83.         }
  84.         size_type copy(charT * buf) const {
  85.             return traits::copy(this->begin(), this->end(), buf);
  86.         }
  87. #if 0   // TODO: Unfinished
  88.         size_type find(basic_string_ref s) const { return ::std::search(this->begin(), this->end(), s.begin(), s.end()) - this->begin(); }
  89.         size_type find(charT c) const { return traits::find(this->begin(), this->size(), c) - this->begin(); }
  90.         size_type rfind(basic_string_ref s) const;
  91.         size_type rfind(charT c) const { return ::std::find(this->rbegin(), this->rend(), c) - this->begin(); }
  92.         size_type find_first_of(basic_string_ref s) const { return this->find(s); }
  93.         size_type find_first_of(charT c) const { return this->find(c); }
  94.         size_type find_first_not_of(basic_string_ref s) const;
  95.         size_type find_first_not_of(charT c) const { return ::std::find_if(this->begin(), this->end(), [c] (charT c_) { return c != c_; }) - this->end(); }
  96.         size_type find_last_of(basic_string_ref s) const;
  97.         size_type find_last_of(charT c) const;
  98.         size_type find_last_not_of(basic_string_ref s) const;
  99.         size_type find_last_not_of(charT c) const;
  100. #endif
  101.         // new string operations
  102.         bool starts_with(basic_string_ref x) const {
  103.             return this->size() >= x.size() ? basic_string_ref(this->begin(), x.size()) == x : false;
  104.         }
  105.         bool ends_with(basic_string_ref x) const {
  106.             return this->size() >= x.size() ? basic_string_ref(this->end() - x.size(), x.size()) == x : false;
  107.         }
  108.  
  109.     private:
  110.         iterator beg_, end_;
  111.     };
  112.  
  113.     // Common specializations:
  114.     typedef basic_string_ref< char > string_ref;
  115.     typedef basic_string_ref< char16_t > u16string_ref;
  116.     typedef basic_string_ref< char32_t > u32string_ref;
  117.     typedef basic_string_ref< wchar_t > wstring_ref;
  118.  
  119.     // Comparison operators
  120.     template<typename charT, typename traits>
  121.     bool operator==(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y) {
  122.         return x.size() == y.size() ? traits::compare(&*x.begin(), &*y.begin(), x.size()) == 0 : false;
  123.     }
  124.     template<typename charT, typename traits>
  125.     bool operator!=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y) {
  126.         return !(x == y);
  127.     }
  128.     template<typename charT, typename traits>
  129.     bool operator<(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
  130.     template<typename charT, typename traits>
  131.     bool operator>(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
  132.     template<typename charT, typename traits>
  133.     bool operator<=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
  134.     template<typename charT, typename traits>
  135.     bool operator>=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
  136.  
  137.     // numeric conversions
  138.     int stoi(const string_ref & str, size_t * idx=0, int base=10);
  139.     long stol(const string_ref & str, size_t * idx=0, int base=10);
  140.     unsigned long stoul(const string_ref & str, size_t * idx=0, int base=10);
  141.     long long stoll(const string_ref & str, size_t * idx=0, int base=10);
  142.     unsigned long long stoull(const string_ref & str, size_t * idx=0, int base=10);
  143.     float stof(const string_ref & str, size_t * idx=0);
  144.     double stod(const string_ref & str, size_t * idx=0);
  145.     long double stold(const string_ref & str, size_t * idx=0);
  146.     int stoi(const wstring_ref & str, size_t * idx=0, int base=10);
  147.     long stol(const wstring_ref & str, size_t * idx=0, int base=10);
  148.     unsigned long stoul(const wstring_ref & str, size_t * idx=0, int base=10);
  149.     long long stoll(const wstring_ref & str, size_t * idx=0, int base=10);
  150.     unsigned long long stoull(const wstring_ref & str, size_t * idx=0, int base=10);
  151.     float stof(const wstring_ref & str, size_t * idx=0);
  152.     double stod(const wstring_ref & str, size_t * idx=0);
  153.     long double stold(const wstring_ref & str, size_t * idx=0);
  154. }
Advertisement
Add Comment
Please, Sign In to add comment