429 lines
8.4 KiB
C++
429 lines
8.4 KiB
C++
|
// file : xsd/cxx/ro-string.hxx
|
||
|
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
|
||
|
|
||
|
#ifndef XSD_CXX_RO_STRING_HXX
|
||
|
#define XSD_CXX_RO_STRING_HXX
|
||
|
|
||
|
#include <string>
|
||
|
#include <cstddef> // std::size_t
|
||
|
#include <ostream>
|
||
|
|
||
|
namespace xsd
|
||
|
{
|
||
|
namespace cxx
|
||
|
{
|
||
|
// Read-only string class template.
|
||
|
//
|
||
|
template <typename C>
|
||
|
class ro_string
|
||
|
{
|
||
|
public:
|
||
|
typedef std::char_traits<C> traits_type;
|
||
|
typedef std::size_t size_type;
|
||
|
|
||
|
static const size_type npos = ~(size_type (0));
|
||
|
|
||
|
public:
|
||
|
ro_string ()
|
||
|
: data_ (0), size_ (0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ro_string (const C* s)
|
||
|
: data_ (s), size_ (traits_type::length (s))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ro_string (const C* s, size_type size)
|
||
|
: data_ (s), size_ (size)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ro_string (const std::basic_string<C>& s)
|
||
|
: data_ (s.data ()), size_ (s.size ())
|
||
|
{
|
||
|
}
|
||
|
|
||
|
operator std::basic_string<C> () const
|
||
|
{
|
||
|
return std::basic_string<C> (data (), size ());
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
ro_string (const ro_string&);
|
||
|
|
||
|
ro_string&
|
||
|
operator= (const ro_string&);
|
||
|
|
||
|
public:
|
||
|
// The returned string is not necessarily terminated with '\0'.
|
||
|
// If size() returns 0, the returned pointer may be 0.
|
||
|
//
|
||
|
const C*
|
||
|
data () const
|
||
|
{
|
||
|
return data_;
|
||
|
}
|
||
|
|
||
|
size_type
|
||
|
size () const
|
||
|
{
|
||
|
return size_;
|
||
|
}
|
||
|
|
||
|
size_type
|
||
|
length () const
|
||
|
{
|
||
|
return size ();
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
bool
|
||
|
empty () const
|
||
|
{
|
||
|
return size () == 0;
|
||
|
}
|
||
|
|
||
|
const C&
|
||
|
operator[] (size_type pos) const
|
||
|
{
|
||
|
return data ()[pos];
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
void
|
||
|
assign (const C* s)
|
||
|
{
|
||
|
data_ = s;
|
||
|
size_ = traits_type::length (s);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
assign (const C* s, size_type size)
|
||
|
{
|
||
|
data_ = s;
|
||
|
size_ = size;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
assign (const std::basic_string<C>& s)
|
||
|
{
|
||
|
data_ = s.c_str ();
|
||
|
size_ = s.size ();
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
int
|
||
|
compare (const ro_string& str) const
|
||
|
{
|
||
|
return compare (str.data (), str.size ());
|
||
|
}
|
||
|
|
||
|
int
|
||
|
compare (const std::basic_string<C>& str) const
|
||
|
{
|
||
|
return compare (str.c_str (), str.size ());
|
||
|
}
|
||
|
|
||
|
int
|
||
|
compare (const C* str) const
|
||
|
{
|
||
|
return compare (str, traits_type::length (str));
|
||
|
}
|
||
|
|
||
|
int
|
||
|
compare (const C* str, size_type n) const
|
||
|
{
|
||
|
size_type s1 (size ());
|
||
|
size_type s (s1 < n ? s1 : n);
|
||
|
|
||
|
int r (s != 0 ? traits_type::compare (data (), str, s) : 0);
|
||
|
|
||
|
if (!r && s1 != n)
|
||
|
r = s1 < n ? -1 : 1;
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
size_type
|
||
|
find (C c, size_type pos = 0) const;
|
||
|
|
||
|
private:
|
||
|
const C* data_;
|
||
|
size_type size_;
|
||
|
};
|
||
|
|
||
|
// operator==
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator== (const ro_string<C>& a, const ro_string<C>& b)
|
||
|
{
|
||
|
return a.compare (b) == 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator== (const ro_string<C>& a, const std::basic_string<C>& b)
|
||
|
{
|
||
|
return a.compare (b) == 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator== (const std::basic_string<C>& a, const ro_string<C>& b)
|
||
|
{
|
||
|
return b.compare (a) == 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator== (const ro_string<C>& a, const C* b)
|
||
|
{
|
||
|
return a.compare (b) == 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator== (const C* a, const ro_string<C>& b)
|
||
|
{
|
||
|
return b.compare (a) == 0;
|
||
|
}
|
||
|
|
||
|
// operator!=
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator!= (const ro_string<C>& a, const ro_string<C>& b)
|
||
|
{
|
||
|
return a.compare (b) != 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator!= (const ro_string<C>& a, const std::basic_string<C>& b)
|
||
|
{
|
||
|
return a.compare (b) != 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator!= (const std::basic_string<C>& a, const ro_string<C>& b)
|
||
|
{
|
||
|
return b.compare (a) != 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator!= (const ro_string<C>& a, const C* b)
|
||
|
{
|
||
|
return a.compare (b) != 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator!= (const C* a, const ro_string<C>& b)
|
||
|
{
|
||
|
return b.compare (a) != 0;
|
||
|
}
|
||
|
|
||
|
// operator<
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator< (const ro_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) < 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator< (const ro_string<C>& l, const std::basic_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) < 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator< (const std::basic_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) > 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator< (const ro_string<C>& l, const C* r)
|
||
|
{
|
||
|
return l.compare (r) < 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator< (const C* l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) > 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// operator>
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator> (const ro_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) > 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator> (const ro_string<C>& l, const std::basic_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) > 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator> (const std::basic_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) < 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator> (const ro_string<C>& l, const C* r)
|
||
|
{
|
||
|
return l.compare (r) > 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator> (const C* l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) < 0;
|
||
|
}
|
||
|
|
||
|
// operator<=
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator<= (const ro_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) <= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator<= (const ro_string<C>& l, const std::basic_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) <= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator<= (const std::basic_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) >= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator<= (const ro_string<C>& l, const C* r)
|
||
|
{
|
||
|
return l.compare (r) <= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator<= (const C* l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) >= 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// operator>=
|
||
|
//
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator>= (const ro_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) >= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator>= (const ro_string<C>& l, const std::basic_string<C>& r)
|
||
|
{
|
||
|
return l.compare (r) >= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator>= (const std::basic_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) <= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator>= (const ro_string<C>& l, const C* r)
|
||
|
{
|
||
|
return l.compare (r) >= 0;
|
||
|
}
|
||
|
|
||
|
template <typename C>
|
||
|
inline bool
|
||
|
operator>= (const C* l, const ro_string<C>& r)
|
||
|
{
|
||
|
return r.compare (l) <= 0;
|
||
|
}
|
||
|
|
||
|
// operator<<
|
||
|
//
|
||
|
template<typename C>
|
||
|
std::basic_ostream<C>&
|
||
|
operator<< (std::basic_ostream<C>& os, const ro_string<C>& str)
|
||
|
{
|
||
|
if (str.size () != 0)
|
||
|
os.write (str.data (), static_cast<std::streamsize> (str.size ()));
|
||
|
|
||
|
return os;
|
||
|
}
|
||
|
|
||
|
// operator+=
|
||
|
//
|
||
|
template<typename C>
|
||
|
std::basic_string<C>&
|
||
|
operator+= (std::basic_string<C>& l, const ro_string<C>& r)
|
||
|
{
|
||
|
l.append (r.data (), r.size ());
|
||
|
return l;
|
||
|
}
|
||
|
|
||
|
// Trim leading and trailing XML whitespaces. Return the new
|
||
|
// string size.
|
||
|
//
|
||
|
template <typename C>
|
||
|
typename ro_string<C>::size_type
|
||
|
trim_left (ro_string<C>&);
|
||
|
|
||
|
template <typename C>
|
||
|
typename ro_string<C>::size_type
|
||
|
trim_right (ro_string<C>&);
|
||
|
|
||
|
template <typename C>
|
||
|
typename ro_string<C>::size_type
|
||
|
trim (ro_string<C>&);
|
||
|
|
||
|
// Trim leading and trailing XML whitespaces.
|
||
|
//
|
||
|
template<typename C>
|
||
|
std::basic_string<C>
|
||
|
trim (const std::basic_string<C>&);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#include <xsd/cxx/ro-string.txx>
|
||
|
|
||
|
#endif // XSD_CXX_RO_STRING_HXX
|