BasicSubString.h
// BasicSubString.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2005
#pragma once
#ifndef Ceda_cxUtils_BasicSubString_H
#define Ceda_cxUtils_BasicSubString_H
#include "xstring.h"
#include "CedaAssert.h"
namespace ceda
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// BasicSubString<T>
// A char range represents a substring of characters in the range [p1,p2). No ownership semantics
// is implied.
template <typename T>
class BasicSubString
{
public:
BasicSubString() : m_p1(nullptr), m_p2(nullptr) {}
BasicSubString(const T* str) : m_p1(str), m_p2(str ? str + GetStringLength(str) : nullptr) {}
BasicSubString(const T* p1, const T* p2) : m_p1(p1), m_p2(p2) {}
BasicSubString(const basic_xstring<T>& s) : m_p1(s.data()), m_p2(s.data()+s.size()) {}
~BasicSubString() {}
explicit operator bool() const { return m_p1 < m_p2; }
ssize_t size() const { return m_p2 - m_p1; }
bool empty() const { return m_p2 == m_p1; }
basic_xstring<T> GetString() const { return basic_xstring<T>(m_p1,m_p2); }
T operator[](ssize_t i) const { return m_p1[i]; }
BasicSubString& operator+=(ssize_t i) { m_p1 += i; cxAssert(m_p1 <= m_p2); return *this; }
BasicSubString& operator-=(ssize_t i) { m_p1 -= i; return *this; }
BasicSubString& operator++() { cxAssert(m_p1 < m_p2); ++m_p1; return *this; }
const BasicSubString operator++(int) { BasicSubString s = *this; ++(*this); return s; }
BasicSubString& operator--() { --m_p1; return *this; }
const BasicSubString operator--(int) { BasicSubString s = *this; --(*this); return s; }
T operator*() const { cxAssert(m_p1 < m_p2); return *m_p1; }
typedef const T* const_iterator;
const_iterator begin() const { return m_p1; }
const_iterator end() const { return m_p2; }
void setbegin(const T* p1) { m_p1 = p1; }
void setend(const T* p2) { m_p2 = p2; }
const T* ptr() const { return m_p1; }
// TODO: The SubString8 typedef needs to be reflected so that cxPython can dispatch python's print
// function to PythonCallback_WriteToStdOut(SubString8 s). However, the Ceda reflection system
// can't reflect private members (offsetof is used to get the address of the member in the object).
//private:
const T* m_p1;
const T* m_p2;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// BasicReversedSubString<T>
// As for BasicSubString<T> except that it processes the characters in reverse order
template <typename T>
class BasicReversedSubString
{
public:
BasicReversedSubString() : m_p1(nullptr), m_p2(nullptr) {}
BasicReversedSubString(const T* str) : m_p1(str - 1), m_p2(str + GetStringLength(str) - 1) {}
BasicReversedSubString(const T* p1, const T* p2) : m_p1(p1-1), m_p2(p2-1) {}
BasicReversedSubString(const basic_xstring<T>& s) : m_p1(s.begin()-1), m_p2(s.end()-1) {}
explicit operator bool() const { return m_p1 < m_p2; }
ssize_t size() const { return m_p2 - m_p1; }
bool empty() const { return m_p2 <= m_p1; }
basic_xstring<T> GetString() const { return basic_xstring<T>(m_p1+1,m_p2+1); }
T operator[](ssize_t i) const { return *(m_p2 - i); }
BasicReversedSubString& operator+=(ssize_t i) { m_p2 -= i; cxAssert(m_p1 <= m_p2); return *this; }
BasicReversedSubString& operator-=(ssize_t i) { m_p2 += i; return *this; }
BasicReversedSubString& operator++() { cxAssert(m_p1 < m_p2); --m_p2; return *this; }
const BasicReversedSubString operator++(int) { BasicReversedSubString s = *this; ++(*this); return s; }
T operator*() const { cxAssert(m_p1 < m_p2); return *m_p2; }
class const_iterator
{
public:
const_iterator(const T* _p) : p(_p) {}
operator const T*() const { return p; }
const T& operator*() const { cxAssert(p); return *p; }
const T* operator->() const { cxAssert(p); return p; }
const_iterator& operator++() { cxAssert(p); --p; return *this; }
const const_iterator operator++(int) { const_iterator it = *this; ++(*this); return it; }
const_iterator& operator--() { cxAssert(p); ++p; return *this; }
const const_iterator operator--(int) { const_iterator it = *this; --(*this); return it; }
bool operator==(const const_iterator& rhs) const { return p == rhs.p; }
bool operator!=(const const_iterator& rhs) const { return p != rhs.p; }
private:
const T* p;
};
const_iterator begin() const { return m_p2; }
const_iterator end() const { return m_p1; }
void setbegin(const T* p2) { m_p2 = p2; }
void setend(const T* p1) { m_p1 = p1; }
const T* ptr() const { return m_p2; }
private:
// represent range of characters (m_p1, m_p2]
const T* m_p1;
const T* m_p2;
};
} // namespace ceda
#endif // include guard