#ifndef CONST_STRING_HEADER_INCLUDED
#define CONST_STRING_HEADER_INCLUDED
#include <iterator>
#include <cstddef>
#include <algorithm>
#include <iostream>
template<typename T>
class basic_const_string
{
public:
typedef const T value_type;
typedef value_type& reference;
typedef value_type& const_reference;
typedef value_type* pointer;
typedef value_type* const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
static const size_type npos;
private:
static size_type stringlength(const_pointer string)
{
size_type i = 0;
while(string[i])
++i;
return i;
}
public:
basic_const_string():
begin_(0),
end_(0)
{}
basic_const_string(const_pointer string, size_type length):
begin_(string),
end_(string + length)
{}
basic_const_string(const_pointer string):
begin_(string),
end_(string + stringlength(string))
{}
basic_const_string(iterator begin, iterator end):
begin_(begin),
end_(end)
{}
const_iterator begin() const
{
return begin_;
}
const_iterator end() const
{
return end_;
}
const_reverse_iterator rbegin() const
{
return reverse_iterator(end());
}
const_reverse_iterator rend() const
{
return reverse_iterator(begin());
}
size_type size() const
{
return end() - begin();
}
value_type operator[](size_type i) const
{
return begin()[i];
}
basic_const_string substr(size_type pos, size_type n = npos) const
{
iterator iter = begin() + pos;
return basic_const_string(iter, iter + std::min(size() - pos, n));
}
size_type find(value_type needle, size_type pos = 0) const
{
for(iterator iter = begin() + pos; iter != end(); ++iter)
{
if(*iter == needle)
{
return iter - begin();
}
}
return npos;
}
size_type find(const basic_const_string& needle, size_type pos = 0) const
{
iterator to_find = needle.begin();
for(iterator iter = begin() + pos; iter != end(); ++iter)
{
if(*iter == *to_find)
{
++to_find;
}
else
{
to_find = needle.begin();
}
if(to_find == needle.end())
{
return iter + 1 - needle.size() - begin();
}
}
return npos;
}
void copy(T* str, size_type num, size_type index = 0) const
{
std::copy(begin() + index, begin() + index + num, str);
}
template<size_type N>
void copy(T (&str)[N], size_type index = 0) const
{
this->copy(str, N, index);
}
private:
iterator begin_;
iterator end_;
};
template<typename T>
const typename basic_const_string<T>::size_type
basic_const_string<T>::npos = typename basic_const_string<T>::size_type(-1);
typedef basic_const_string<char> const_string;
typedef basic_const_string<wchar_t> const_wstring;
template<typename T, typename CharTraits>
std::basic_ostream<T, CharTraits>& operator<<(std::basic_ostream<T, CharTraits>& os, const basic_const_string<T>& str)
{
std::copy(str.begin(), str.end(), std::ostream_iterator<T, typename CharTraits::char_type, CharTraits>(os));
return os;
}
template<typename T>
int compare(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
typedef typename basic_const_string<T>::const_iterator iterator;
iterator l = lhs.begin();
iterator r = rhs.begin();
for(; l != lhs.end() && r != rhs.end(); ++l, ++r)
{
if(*l < *r)
{
return -1;
}
else if(*l > *r)
{
return 1;
}
}
if(r != rhs.end())
{
return -1;
}
return l != lhs.end();
}
template<typename T>
bool operator==(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return compare(lhs, rhs) == 0;
}
template<typename T>
bool operator==(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) == rhs;
}
template<typename T>
bool operator==(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs == basic_const_string<T>(rhs);
}
template<typename T>
bool operator!=(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return !(lhs == rhs);
}
template<typename T>
bool operator!=(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) != rhs;
}
template<typename T>
bool operator!=(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs != basic_const_string<T>(rhs);
}
template<typename T>
bool operator<(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return compare(lhs, rhs) == -1;
}
template<typename T>
bool operator<(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) < rhs;
}
template<typename T>
bool operator<(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs < basic_const_string<T>(rhs);
}
template<typename T>
bool operator>(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return rhs < lhs;
}
template<typename T>
bool operator>(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) > rhs;
}
template<typename T>
bool operator>(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs > basic_const_string<T>(rhs);
}
template<typename T>
bool operator<=(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return !(lhs > rhs);
}
template<typename T>
bool operator<=(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) <= rhs;
}
template<typename T>
bool operator<=(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs <= basic_const_string<T>(rhs);
}
template<typename T>
bool operator>=(const basic_const_string<T>& lhs, const basic_const_string<T>& rhs)
{
return !(lhs < rhs);
}
template<typename T>
bool operator>=(const T* lhs, const basic_const_string<T>& rhs)
{
return basic_const_string<T>(lhs) >= rhs;
}
template<typename T>
bool operator>=(const basic_const_string<T>& lhs, const T* rhs)
{
return lhs >= basic_const_string<T>(rhs);
}
#endif