Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cassert>
- #include <string>
- #include <cstring>
- #include <algorithm>
- #include <stdexcept>
- namespace std {
- template<typename charT, typename traits = char_traits<charT>>
- class basic_string_ref {
- public:
- // types
- typedef charT value_type;
- typedef const charT * pointer;
- typedef const charT & reference;
- typedef const charT & const_reference;
- typedef const charT * const_iterator;
- typedef const_iterator iterator;
- typedef ::std::reverse_iterator< const_iterator > const_reverse_iterator;
- typedef const_reverse_iterator reverse_iterator;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- static constexpr size_type npos = size_type(-1);
- // construct/copy
- constexpr basic_string_ref(): beg_(""), end_(beg_) {}
- constexpr basic_string_ref(const basic_string_ref &rhs): beg_(rhs.beg_), end_(rhs.end_) {}
- basic_string_ref & operator=(const basic_string_ref &rhs) { this->beg_= rhs.beg_; this->end_ = rhs.end_; }
- basic_string_ref(const charT * str): beg_(str), end_(beg_ + ::std::strlen(str)) {}
- template<typename Allocator>
- basic_string_ref(const basic_string< charT, traits, Allocator > & str): beg_(&*str.begin()), end_(beg_ + str.size()) {}
- constexpr basic_string_ref(const charT * str, size_type len): beg_(str), end_(beg_ + len) {}
- // iterators
- constexpr const_iterator begin() const { return beg_; }
- constexpr const_iterator end() const { return end_; }
- constexpr const_iterator cbegin() const { return beg_; }
- constexpr const_iterator cend() const { return end_; }
- const_reverse_iterator rbegin() const { return end_; }
- const_reverse_iterator rend() const { return beg_; }
- const_reverse_iterator crbegin() const { return end_; }
- const_reverse_iterator crend() const { return beg_; }
- // capacity
- constexpr size_type size() const { return end_ - beg_; }
- constexpr size_type max_size() const { return this->size(); }
- constexpr bool empty() const { return beg_ == end_; }
- constexpr size_type length() const { return this->size(); }
- // element access
- constexpr const charT & operator[](size_t i) const {
- assert(i < this->size());
- return beg_[i];
- }
- const charT & at(size_t i) const {
- if (i >= this->size())
- throw ::std::length_error("basic_string_ref::at");
- return beg_[i];
- }
- constexpr const charT & front() const { return beg_[0]; }
- constexpr const charT & back() const { return end_[-1]; }
- constexpr const charT * data() const { return beg_; }
- // Outgoing conversion operators
- // constexpr operator array_ref< const charT >() const;
- template<typename Allocator>
- explicit operator basic_string< charT, traits, Allocator >() const { return basic_string< charT, traits >(begin(), end()); }
- basic_string< charT, traits > str() const { return basic_string< charT, traits >(*this); }
- // mutators
- void clear() { beg_ = end_ = ""; }
- void remove_prefix(size_type n) { beg_ += n; assert(beg_ <= end_); }
- void remove_suffix(size_type n) { end_ -= n; assert(end_ >= beg_); }
- void pop_back() { this->remove_prefix(1); }
- void pop_front() { this->remove_suffix(1); }
- // string operations with the same semantics as ::std::basic_string
- int compare(basic_string_ref x) const {
- return traits::compare(this->begin(), this->end(), ::std::min(this->size(), x.size()) + 1);
- // return ::std::lexicographical_compare(this->begin(), this->end(), x.begin(), x.end());
- }
- constexpr basic_string_ref substr(size_type pos, size_type n=npos) const {
- return basic_string_ref(this->begin() + pos, pos + n <= this->size() ? this->begin() + pos + n : this->end());
- }
- size_type copy(charT * buf) const {
- return traits::copy(this->begin(), this->end(), buf);
- }
- #if 0 // TODO: Unfinished
- size_type find(basic_string_ref s) const { return ::std::search(this->begin(), this->end(), s.begin(), s.end()) - this->begin(); }
- size_type find(charT c) const { return traits::find(this->begin(), this->size(), c) - this->begin(); }
- size_type rfind(basic_string_ref s) const;
- size_type rfind(charT c) const { return ::std::find(this->rbegin(), this->rend(), c) - this->begin(); }
- size_type find_first_of(basic_string_ref s) const { return this->find(s); }
- size_type find_first_of(charT c) const { return this->find(c); }
- size_type find_first_not_of(basic_string_ref s) const;
- 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(); }
- size_type find_last_of(basic_string_ref s) const;
- size_type find_last_of(charT c) const;
- size_type find_last_not_of(basic_string_ref s) const;
- size_type find_last_not_of(charT c) const;
- #endif
- // new string operations
- bool starts_with(basic_string_ref x) const {
- return this->size() >= x.size() ? basic_string_ref(this->begin(), x.size()) == x : false;
- }
- bool ends_with(basic_string_ref x) const {
- return this->size() >= x.size() ? basic_string_ref(this->end() - x.size(), x.size()) == x : false;
- }
- private:
- iterator beg_, end_;
- };
- // Common specializations:
- typedef basic_string_ref< char > string_ref;
- typedef basic_string_ref< char16_t > u16string_ref;
- typedef basic_string_ref< char32_t > u32string_ref;
- typedef basic_string_ref< wchar_t > wstring_ref;
- // Comparison operators
- template<typename charT, typename traits>
- bool operator==(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y) {
- return x.size() == y.size() ? traits::compare(&*x.begin(), &*y.begin(), x.size()) == 0 : false;
- }
- template<typename charT, typename traits>
- bool operator!=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y) {
- return !(x == y);
- }
- template<typename charT, typename traits>
- bool operator<(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
- template<typename charT, typename traits>
- bool operator>(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
- template<typename charT, typename traits>
- bool operator<=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
- template<typename charT, typename traits>
- bool operator>=(basic_string_ref< charT, traits > x, basic_string_ref< charT, traits > y);
- // numeric conversions
- int stoi(const string_ref & str, size_t * idx=0, int base=10);
- long stol(const string_ref & str, size_t * idx=0, int base=10);
- unsigned long stoul(const string_ref & str, size_t * idx=0, int base=10);
- long long stoll(const string_ref & str, size_t * idx=0, int base=10);
- unsigned long long stoull(const string_ref & str, size_t * idx=0, int base=10);
- float stof(const string_ref & str, size_t * idx=0);
- double stod(const string_ref & str, size_t * idx=0);
- long double stold(const string_ref & str, size_t * idx=0);
- int stoi(const wstring_ref & str, size_t * idx=0, int base=10);
- long stol(const wstring_ref & str, size_t * idx=0, int base=10);
- unsigned long stoul(const wstring_ref & str, size_t * idx=0, int base=10);
- long long stoll(const wstring_ref & str, size_t * idx=0, int base=10);
- unsigned long long stoull(const wstring_ref & str, size_t * idx=0, int base=10);
- float stof(const wstring_ref & str, size_t * idx=0);
- double stod(const wstring_ref & str, size_t * idx=0);
- long double stold(const wstring_ref & str, size_t * idx=0);
- }
Advertisement
Add Comment
Please, Sign In to add comment