Skip to content

Instantly share code, notes, and snippets.

@kikairoya
Created October 14, 2011 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kikairoya/1286400 to your computer and use it in GitHub Desktop.
Save kikairoya/1286400 to your computer and use it in GitHub Desktop.
string_piece
#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