2012-04-14 10:06:21 +00:00
|
|
|
#ifndef SPROUT_STRING_CHAR_TRAITS_HPP
|
|
|
|
#define SPROUT_STRING_CHAR_TRAITS_HPP
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <string>
|
|
|
|
#include <sprout/config.hpp>
|
2012-12-21 13:35:48 +00:00
|
|
|
#include <sprout/functional/bind2nd.hpp>
|
|
|
|
#include <sprout/iterator/ptr_index_iterator.hpp>
|
2013-01-11 19:08:44 +00:00
|
|
|
#include <sprout/algorithm/find_if.hpp>
|
2012-12-21 14:12:54 +00:00
|
|
|
#include <sprout/algorithm/tristate_lexicographical_compare.hpp>
|
2013-01-03 08:01:50 +00:00
|
|
|
#include <sprout/iterator/operation.hpp>
|
2013-01-12 16:16:48 +00:00
|
|
|
#include <sprout/cstring/strlen.hpp>
|
2012-04-14 10:06:21 +00:00
|
|
|
|
|
|
|
namespace sprout {
|
|
|
|
//
|
|
|
|
// char_traits
|
|
|
|
//
|
|
|
|
template<typename Char>
|
|
|
|
class char_traits {
|
|
|
|
private:
|
|
|
|
typedef std::char_traits<Char> impl_type;
|
|
|
|
public:
|
|
|
|
typedef typename impl_type::char_type char_type;
|
|
|
|
typedef typename impl_type::int_type int_type;
|
|
|
|
typedef typename impl_type::off_type off_type;
|
|
|
|
typedef typename impl_type::pos_type pos_type;
|
|
|
|
typedef typename impl_type::state_type state_type;
|
2012-12-21 13:35:48 +00:00
|
|
|
private:
|
|
|
|
struct eq_ {
|
|
|
|
public:
|
|
|
|
SPROUT_CONSTEXPR bool operator()(char_type c1, char_type c2) const SPROUT_NOEXCEPT {
|
|
|
|
return eq(c1, c2);
|
|
|
|
}
|
|
|
|
};
|
2012-12-21 14:12:54 +00:00
|
|
|
struct lt_ {
|
|
|
|
public:
|
|
|
|
SPROUT_CONSTEXPR bool operator()(char_type c1, char_type c2) const SPROUT_NOEXCEPT {
|
|
|
|
return lt(c1, c2);
|
|
|
|
}
|
|
|
|
};
|
2012-12-21 13:35:48 +00:00
|
|
|
private:
|
|
|
|
static SPROUT_CONSTEXPR char_type const* find_impl(char_type const* found, char_type const* last) {
|
|
|
|
return found == last ? nullptr
|
|
|
|
: found
|
|
|
|
;
|
|
|
|
}
|
2012-04-14 10:06:21 +00:00
|
|
|
public:
|
|
|
|
static void assign(char_type& c1, char_type const& c2) SPROUT_NOEXCEPT {
|
|
|
|
impl_type::assign(c1, c2);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR bool eq(char_type c1, char_type c2) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::eq(c1, c2);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR bool lt(char_type c1, char_type c2) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::lt(c1, c2);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR int compare(char_type const* s1, char_type const* s2, std::size_t n) {
|
2012-12-21 14:12:54 +00:00
|
|
|
return sprout::tristate_lexicographical_compare(
|
2012-12-21 17:53:21 +00:00
|
|
|
sprout::as_iterator(s1), sprout::as_iterator(s1, n), char_type(),
|
|
|
|
sprout::as_iterator(s2), sprout::as_iterator(s2, n), char_type(),
|
2012-12-21 14:12:54 +00:00
|
|
|
lt_()
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR std::size_t length(char_type const* s) {
|
2013-01-12 16:16:48 +00:00
|
|
|
return sprout::detail::strlen(s);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
|
2012-12-21 13:35:48 +00:00
|
|
|
return find_impl(
|
|
|
|
sprout::as_iterator_base(
|
2013-01-11 19:08:44 +00:00
|
|
|
sprout::find_if(
|
2012-12-21 13:35:48 +00:00
|
|
|
sprout::as_iterator(s), sprout::as_iterator(s, n),
|
|
|
|
sprout::bind2nd(eq_(), a)
|
|
|
|
)
|
|
|
|
),
|
|
|
|
s + n
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
static char_type* move(char_type* s1, char_type const* s2, std::size_t n) {
|
|
|
|
return impl_type::move(s1, s2, n);
|
|
|
|
}
|
|
|
|
static char_type* copy(char_type* s1, char_type const* s2, std::size_t n) {
|
|
|
|
return impl_type::copy(s1, s2, n);
|
|
|
|
}
|
|
|
|
static char_type* assign(char_type* s, std::size_t n, char_type a) {
|
|
|
|
return impl_type::assign(s, n, a);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR int_type not_eof(int_type c) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::not_eof(c);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR char_type to_char_type(int_type c) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::to_char_type(c);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR int_type to_int_type(char_type c) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::to_int_type(c);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR bool eq_int_type(int_type c1, int_type c2) SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::eq_int_type(c1, c2);
|
|
|
|
}
|
|
|
|
static SPROUT_CONSTEXPR int_type eof() SPROUT_NOEXCEPT {
|
|
|
|
return impl_type::eof();
|
|
|
|
}
|
|
|
|
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR int compare(char_type const* s1, ConstIterator s2, std::size_t n) {
|
2012-12-21 14:12:54 +00:00
|
|
|
return sprout::tristate_lexicographical_compare(
|
2012-12-21 17:53:21 +00:00
|
|
|
sprout::as_iterator(s1), sprout::as_iterator(s1, n), char_type(),
|
|
|
|
s2, s2 + n, char_type(),
|
2012-12-21 14:12:54 +00:00
|
|
|
lt_()
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR int compare(ConstIterator s1, char_type const* s2, std::size_t n) {
|
2012-12-21 14:12:54 +00:00
|
|
|
return sprout::tristate_lexicographical_compare(
|
2012-12-21 17:53:21 +00:00
|
|
|
s1, s1 + n, char_type(),
|
|
|
|
sprout::as_iterator(s2), sprout::as_iterator(s2, n), char_type(),
|
2012-12-21 14:12:54 +00:00
|
|
|
lt_()
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
template<typename ConstIterator1, typename ConstIterator2>
|
|
|
|
static SPROUT_CONSTEXPR int compare(ConstIterator1 s1, ConstIterator2 s2, std::size_t n) {
|
2012-12-21 14:12:54 +00:00
|
|
|
return sprout::tristate_lexicographical_compare(
|
2012-12-21 17:53:21 +00:00
|
|
|
s1, s1 + n, char_type(),
|
|
|
|
s2, s2 + n, char_type(),
|
2012-12-21 14:12:54 +00:00
|
|
|
lt_()
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s) {
|
2013-01-12 16:16:48 +00:00
|
|
|
return sprout::detail::strlen(s);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
2012-12-21 13:35:48 +00:00
|
|
|
return sprout::as_iterator_base(
|
2013-01-11 19:08:44 +00:00
|
|
|
sprout::find_if(
|
2012-12-21 13:35:48 +00:00
|
|
|
s, s + n,
|
|
|
|
sprout::bind2nd(eq_(), a)
|
|
|
|
)
|
|
|
|
);
|
2012-04-14 10:06:21 +00:00
|
|
|
}
|
|
|
|
template<typename Iterator, typename ConstIterator>
|
|
|
|
static Iterator move(Iterator s1, ConstIterator s2, std::size_t n) {
|
|
|
|
std::copy_backward(s2, s2 + n, s1);
|
|
|
|
return s1;
|
|
|
|
}
|
|
|
|
template<typename Iterator, typename ConstIterator>
|
|
|
|
static Iterator copy(Iterator s1, ConstIterator s2, std::size_t n) {
|
|
|
|
std::copy(s2, s2 + n, s1);
|
|
|
|
return s1;
|
|
|
|
}
|
|
|
|
template<typename Iterator>
|
|
|
|
static Iterator assign(Iterator s, std::size_t n, char_type a) {
|
|
|
|
std::fill(s, s + n, a);
|
|
|
|
return s;
|
|
|
|
}
|
2012-10-08 05:14:59 +00:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// char_traits_helper
|
|
|
|
//
|
|
|
|
template<typename Traits>
|
|
|
|
class char_traits_helper {
|
|
|
|
public:
|
|
|
|
typedef Traits traits_type;
|
|
|
|
typedef typename traits_type::char_type char_type;
|
|
|
|
typedef typename traits_type::int_type int_type;
|
|
|
|
typedef typename traits_type::off_type off_type;
|
|
|
|
typedef typename traits_type::pos_type pos_type;
|
|
|
|
typedef typename traits_type::state_type state_type;
|
2012-12-21 13:35:48 +00:00
|
|
|
private:
|
|
|
|
struct eq_ {
|
|
|
|
public:
|
|
|
|
SPROUT_CONSTEXPR bool operator()(char_type c1, char_type c2) const SPROUT_NOEXCEPT {
|
|
|
|
return traits_type::eq(c1, c2);
|
|
|
|
}
|
|
|
|
};
|
2012-10-08 05:14:59 +00:00
|
|
|
public:
|
2012-12-21 13:35:48 +00:00
|
|
|
static SPROUT_CONSTEXPR std::size_t length(char_type const* s, std::size_t n) {
|
2013-01-03 08:01:50 +00:00
|
|
|
return sprout::distance(
|
2012-12-21 13:35:48 +00:00
|
|
|
sprout::as_iterator(s),
|
|
|
|
find(sprout::as_iterator(s), n, char_type())
|
|
|
|
);
|
|
|
|
}
|
2012-10-08 12:29:35 +00:00
|
|
|
static SPROUT_CONSTEXPR char_type const* find(char_type const* s, std::size_t n, char_type const& a) {
|
2012-12-21 13:35:48 +00:00
|
|
|
return sprout::as_iterator_base(
|
2013-01-11 19:08:44 +00:00
|
|
|
sprout::find_if(
|
2012-12-21 13:35:48 +00:00
|
|
|
sprout::as_iterator(s), sprout::as_iterator(s, n),
|
|
|
|
sprout::bind2nd(eq_(), a)
|
|
|
|
)
|
|
|
|
);
|
2012-10-08 12:29:35 +00:00
|
|
|
}
|
2012-10-08 05:14:59 +00:00
|
|
|
static SPROUT_CONSTEXPR bool is_found(char_type const* found, char_type const* last) {
|
2012-10-08 12:29:35 +00:00
|
|
|
return found != last;
|
2012-10-08 05:14:59 +00:00
|
|
|
}
|
|
|
|
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
|
2012-12-21 13:35:48 +00:00
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR std::size_t length(ConstIterator s, std::size_t n) {
|
2013-01-03 08:01:50 +00:00
|
|
|
return sprout::distance(
|
2012-12-21 13:35:48 +00:00
|
|
|
s,
|
|
|
|
find(s, n, char_type())
|
|
|
|
);
|
|
|
|
}
|
2012-10-08 12:29:35 +00:00
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR ConstIterator find(ConstIterator s, std::size_t n, char_type const& a) {
|
2013-01-11 19:08:44 +00:00
|
|
|
return sprout::find_if(
|
2012-12-21 13:35:48 +00:00
|
|
|
s, s + n,
|
|
|
|
sprout::bind2nd(eq_(), a)
|
|
|
|
);
|
2012-10-08 12:29:35 +00:00
|
|
|
}
|
2012-10-08 05:14:59 +00:00
|
|
|
template<typename ConstIterator>
|
|
|
|
static SPROUT_CONSTEXPR bool is_found(ConstIterator found, ConstIterator last) {
|
|
|
|
return found != last;
|
|
|
|
}
|
2012-04-14 10:06:21 +00:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
} // namespace sprout
|
|
|
|
|
|
|
|
#endif // #ifndef SPROUT_STRING_CHAR_TRAITS_HPP
|