Created
October 14, 2011 06:32
-
-
Save kikairoya/1286400 to your computer and use it in GitHub Desktop.
string_piece
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <iterator> | |
template <typename charT> | |
class basic_string_piece { | |
public: | |
typedef std::char_traits<charT> trait_type; | |
typedef typename trait_type::char_type char_type; | |
typedef const char_type *const_pointer; | |
typedef const char_type &const_reference; | |
typedef std::basic_string<char_type> string_type; | |
typedef typename trait_type::size_type size_type; | |
static const size_type npos = string_type::npos; | |
struct const_iterator: std::iterator<std::random_access_iterator_tag, const char_type> { | |
typedef std::iterator<std::random_access_iterator_tag, const char_type> base_type; | |
const_iterator(): r(), p() { } | |
explicit const_iterator(const basic_string_piece<charT> *r, size_type p = 0): r(r), p(p) { } | |
const_iterator &operator ++() { ++p; return *this; } | |
const_iterator operator ++(int) { const_iterator tmp(*this); ++*this; return tmp; } | |
const_iterator &operator --() { --p; return *this; } | |
const_iterator operator --(int) { const_iterator tmp(*this); --*this; return tmp; } | |
char_type operator *() const { return r[p]; } | |
char_type operator [](size_type n) const { return r[p+n]; } | |
const_iterator &operator +=(typename base_type::difference_type n) { p += n; return *this; } | |
const_iterator &operator -=(typename base_type::difference_type n) { p -= n; return *this; } | |
friend const_iterator operator +(const_iterator i, typename base_type::difference_type n) { return i += n; } | |
friend const_iterator operator +(typename base_type::difference_type n, const_iterator i) { return i += n; } | |
friend const_iterator operator -(const_iterator i, typename base_type::difference_type n) { return i -= n; } | |
friend typename base_type::difference_type operator -(const_iterator i, const_iterator j) { return i.p - j.p; } | |
friend bool operator < (const_iterator x, const_iterator y) { return x.p < y.p; } | |
friend bool operator <=(const_iterator x, const_iterator y) { return x.p <=y.p; } | |
friend bool operator >=(const_iterator x, const_iterator y) { return x.p >=y.p; } | |
friend bool operator > (const_iterator x, const_iterator y) { return x.p > y.p; } | |
private: | |
const basic_string_piece<charT> *r; | |
size_type p; | |
}; | |
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
public: | |
basic_string_piece(const_pointer ptr = 0): ptr(ptr), len(ptr ? trait_type::length(ptr) : 0) { } | |
basic_string_piece(string_type ptr) { this->ptr.stdstr = ptr; len = npos; } | |
public: | |
size_type length() const { return cstrp() ? len : ptr.stdstr->length(); } | |
char_type operator [](size_type pos) const { return cstrp() ? (*ptr.cstr)[pos] : (*ptr.stdstr)[pos]; } | |
char_type at(size_type pos) const { if (length()<=pos) throw std::range_error(); return (*this)[pos]; } | |
const_pointer c_str() const { return cstrp() ? ptr.cstr : ptr.stdstr->c_str(); } | |
bool empty() const { return cstrp() ? len==0 : ptr.stdstr->empty(); } | |
public: | |
const_iterator begin() const { return const_iterator(*this); } | |
const_iterator end() const { return const_iterator(*this, length()); } | |
const_iterator cbegin() const { return begin(); } | |
const_iterator cend() const { return end(); } | |
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } | |
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } | |
const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } | |
const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } | |
private: | |
bool cstrp() const { return len != npos; } | |
union { | |
const_pointer cstr; | |
const string_type *stdstr; | |
} ptr; | |
size_type len; | |
}; | |
typedef basic_string_piece<char> string_piece; | |
typedef basic_string_piece<wchar_t> wstring_piece; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment