ditch char_traits in string stuff

master
Daniel Kolesa 2017-12-15 23:32:06 +01:00
parent 84fc2bc9c4
commit f7929a1b45
4 changed files with 72 additions and 79 deletions

View File

@ -55,19 +55,17 @@ struct arg_error: std::runtime_error {
* This range type has immutable contents and doesn't own its memory. It
* is represented as a regular string slice with the appropraite character
* and traits types. The `T` template type is a character type, usually
* a `char` but can be `wchar_t`, `char16_t`, `char32_t` as well. The
* `TR` template type is the traits type, by default std::char_traits
* for `T`.
* a `char` but can be `wchar_t`, `char16_t`, `char32_t` as well.
*/
template<typename T, typename TR = std::char_traits<T>>
using arg_value_type = basic_char_range<T const, TR>;
template<typename T>
using arg_value_type = basic_char_range<T const>;
/** @brief The range type passed to argument action callbacks.
*
* It's a contiguous range of `const` ostd::arg_value_type.
*/
template<typename T, typename TR = std::char_traits<T>>
using arg_value_range = iterator_range<arg_value_type<T, TR> const *>;
template<typename T>
using arg_value_range = iterator_range<arg_value_type<T> const *>;
/** @brief The type of an argument class. */
enum class arg_type {

View File

@ -1486,7 +1486,7 @@ private:
using value_type = wchar_t;
using pointer = wchar_t *;
using reference = wchar_t &;
using difference_type = typename std::char_traits<wchar_t>::off_type;
using difference_type = std::streamoff;
fmt_out &operator=(wchar_t c) {
char buf[MB_LEN_MAX];

View File

@ -73,21 +73,19 @@ namespace ostd {
* This is a contiguous range over a character type. The character type
* can be any of the standard character types, of any size - for example
* you would use `char32_t` to represent UTF-32 slices. The std::char_traits
* structure (or its equivalent) is used for the basic string operations
* where possible.
* structure is used for the basic string operations where possible.
*
* The range is mutable, i.e. it implements the output range interface.
*/
template<typename T, typename TR = std::char_traits<std::remove_const_t<T>>>
template<typename T>
struct basic_char_range: input_range<basic_char_range<T>> {
using range_category = contiguous_range_tag;
using value_type = T;
using reference = T &;
using size_type = std::size_t;
using traits_type = TR;
private:
using TR = std::char_traits<std::remove_const_t<T>>;
struct nat {};
public:
@ -115,8 +113,7 @@ public:
* if the input is a static array of `T`, the entire array is used to
* create the slice, minus the potential zero at the end. If there is
* no zero at the end, nothing is removed and the array is used whole.
* If the input is not an array, the size is not known at compile time
* and the traits_type is used to check the length.
* If the input is not an array, the size is checked at runtime.
*/
template<typename U>
basic_char_range(U &&beg, std::enable_if_t<
@ -148,10 +145,10 @@ public:
* the new slice's value type, otherwise the constructor will not
* be enabled.
*/
template<typename U, typename TTR, typename = std::enable_if_t<
template<typename U, typename = std::enable_if_t<
std::is_convertible_v<U *, value_type *>
>>
basic_char_range(basic_char_range<U, TTR> const &v) noexcept:
basic_char_range(basic_char_range<U> const &v) noexcept:
p_beg(&v[0]), p_end(&v[v.size()])
{}
@ -174,7 +171,6 @@ public:
/** @brief Assigns the slice's data from a pointer.
*
* The data pointed to by the argument must be zero terminated.
* The traits_type is used to check the length of the string.
*/
basic_char_range &operator=(value_type *s) noexcept {
p_beg = s; p_end = s + (s ? TR::length(s) : 0); return *this;
@ -288,8 +284,8 @@ public:
*
* If this slice is empty and the other is not, this method returns
* -1. If it's the other way around, it returns 1. If both are empty,
* 0 is returned. Otherwise, the `compare` method of traits_type
* to compare the data, using the smaller of the lengths as the
* 0 is returned. Otherwise, the `compare` method of std::char_traits
* is used to compare the data, using the smaller of the lengths as the
* count.
*
* It is not a part of the range interface, just the string slice
@ -318,8 +314,7 @@ diffsize:
*
* Returns a negative value when this slice is less than the other
* slice and a positive value when the other way around. Zero is
* returned when they're equal. The traits_type is not used to
* compare here, as it provides no case-insensitive comparison.
* returned when they're equal.
*/
int case_compare(basic_char_range<value_type const> s) const noexcept {
size_type s1 = size(), s2 = s.size();
@ -363,61 +358,61 @@ using string_range = basic_char_range<char const>;
/* comparisons between ranges */
/** @brief Like `!lhs.compare(rhs)`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator==(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return !lhs.compare(rhs);
}
/** @brief Like `lhs.compare(rhs)`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator!=(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return lhs.compare(rhs);
}
/** @brief Like `lhs.compare(rhs) < 0`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return lhs.compare(rhs) < 0;
}
/** @brief Like `lhs.compare(rhs) > 0`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return lhs.compare(rhs) > 0;
}
/** @brief Like `lhs.compare(rhs) <= 0`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<=(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return lhs.compare(rhs) <= 0;
}
/** @brief Like `lhs.compare(rhs) >= 0`. */
template<typename T, typename U, typename TR>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>=(
basic_char_range<T, TR> lhs, basic_char_range<U, TR> rhs
basic_char_range<T> lhs, basic_char_range<U> rhs
) noexcept {
return lhs.compare(rhs) >= 0;
}
@ -425,98 +420,98 @@ inline std::enable_if_t<
/* comparisons between ranges and char arrays */
/** @brief Like `!lhs.compare(rhs)`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator==(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator==(basic_char_range<T> lhs, U *rhs) noexcept {
return !lhs.compare(rhs);
}
/** @brief Like `lhs.compare(rhs)`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator!=(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator!=(basic_char_range<T> lhs, U *rhs) noexcept {
return lhs.compare(rhs);
}
/** @brief Like `lhs.compare(rhs) < 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator<(basic_char_range<T> lhs, U *rhs) noexcept {
return lhs.compare(rhs) < 0;
}
/** @brief Like `lhs.compare(rhs) > 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator>(basic_char_range<T> lhs, U *rhs) noexcept {
return lhs.compare(rhs) > 0;
}
/** @brief Like `lhs.compare(rhs) <= 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<=(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator<=(basic_char_range<T> lhs, U *rhs) noexcept {
return lhs.compare(rhs) <= 0;
}
/** @brief Like `lhs.compare(rhs) >= 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>=(basic_char_range<T, TR> lhs, U *rhs) noexcept {
> operator>=(basic_char_range<T> lhs, U *rhs) noexcept {
return lhs.compare(rhs) >= 0;
}
/** @brief Like `!rhs.compare(lhs)`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator==(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator==(U *lhs, basic_char_range<T> rhs) noexcept {
return !rhs.compare(lhs);
}
/** @brief Like `rhs.compare(lhs)`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator!=(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator!=(U *lhs, basic_char_range<T> rhs) noexcept {
return rhs.compare(lhs);
}
/** @brief Like `rhs.compare(lhs) > 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator<(U *lhs, basic_char_range<T> rhs) noexcept {
return rhs.compare(lhs) > 0;
}
/** @brief Like `rhs.compare(lhs) < 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator>(U *lhs, basic_char_range<T> rhs) noexcept {
return rhs.compare(lhs) < 0;
}
/** @brief Like `rhs.compare(lhs) >= 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<=(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator<=(U *lhs, basic_char_range<T> rhs) noexcept {
return rhs.compare(lhs) >= 0;
}
/** @brief Like `rhs.compare(lhs) <= 0`. */
template<typename T, typename TR, typename U>
template<typename T, typename U>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>=(U *lhs, basic_char_range<T, TR> rhs) noexcept {
> operator>=(U *lhs, basic_char_range<T> rhs) noexcept {
return rhs.compare(lhs) <= 0;
}
@ -527,7 +522,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator==(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return !lhs.compare(rhs);
}
@ -537,7 +532,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator!=(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return lhs.compare(rhs);
}
@ -547,7 +542,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return lhs.compare(rhs) < 0;
}
@ -557,7 +552,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return lhs.compare(rhs) > 0;
}
@ -567,7 +562,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<=(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return lhs.compare(rhs) <= 0;
}
@ -577,7 +572,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>=(
basic_char_range<T, TR> lhs, std::basic_string<U, TR, A> const &rhs
basic_char_range<T> lhs, std::basic_string<U, TR, A> const &rhs
) noexcept {
return lhs.compare(rhs) >= 0;
}
@ -587,7 +582,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator==(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return !rhs.compare(lhs);
}
@ -597,7 +592,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator!=(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return rhs.compare(lhs);
}
@ -607,7 +602,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return rhs.compare(lhs) > 0;
}
@ -617,7 +612,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return rhs.compare(lhs) < 0;
}
@ -627,7 +622,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator<=(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return rhs.compare(lhs) >= 0;
}
@ -637,7 +632,7 @@ template<typename T, typename TR, typename U, typename A>
inline std::enable_if_t<
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<U>>, bool
> operator>=(
std::basic_string<U, TR, A> const &lhs, basic_char_range<T, TR> rhs
std::basic_string<U, TR, A> const &lhs, basic_char_range<T> rhs
) noexcept {
return rhs.compare(lhs) <= 0;
}
@ -658,7 +653,7 @@ inline bool starts_with(string_range a, string_range b) noexcept {
template<typename T, typename TR, typename A>
struct ranged_traits<std::basic_string<T, TR, A>> {
/** @brief The range type. */
using range = basic_char_range<T, TR>;
using range = basic_char_range<T>;
/** @brief Creates a range. */
static range iter(std::basic_string<T, TR, A> &v) noexcept {
@ -674,7 +669,7 @@ struct ranged_traits<std::basic_string<T, TR, A>> {
template<typename T, typename TR, typename A>
struct ranged_traits<std::basic_string<T, TR, A> const> {
/** @brief The range type. */
using range = basic_char_range<T const, TR>;
using range = basic_char_range<T const>;
/** @brief Creates a range. */
static range iter(std::basic_string<T, TR, A> const &v) noexcept {
@ -723,12 +718,12 @@ namespace std {
* It uses the hashing used for matching std::basic_string_view,
* so the algorithm (and thus result) will always match standard strings.
*/
template<typename T, typename TR>
struct hash<ostd::basic_char_range<T, TR>> {
std::size_t operator()(ostd::basic_char_range<T, TR> const &v)
template<typename T>
struct hash<ostd::basic_char_range<T>> {
std::size_t operator()(ostd::basic_char_range<T> const &v)
const noexcept
{
return hash<std::basic_string_view<std::remove_const_t<T>, TR>>{}(v);
return hash<std::basic_string_view<std::remove_const_t<T>>>{}(v);
}
};

View File

@ -161,7 +161,7 @@ OSTD_EXPORT void subprocess::open_impl(
for (string_range r; func(r, datap);) {
auto sz = r.size();
char *str = new char[sz + 1];
string_range::traits_type::copy(str, r.data(), sz)[sz] = '\0';
std::char_traits<char>::copy(str, r.data(), sz)[sz] = '\0';
argp.vec.push_back(str);
}
@ -177,7 +177,7 @@ OSTD_EXPORT void subprocess::open_impl(
} else {
auto sz = cmd.size();
char *str = new char[sz + 1];
string_range::traits_type::copy(str, cmd.data(), sz)[sz] = '\0';
std::char_traits<char>::copy(str, cmd.data(), sz)[sz] = '\0';
argp.cmd = str;
}
@ -192,7 +192,7 @@ OSTD_EXPORT void subprocess::open_impl(
for (string_range r; efunc(r, edatap);) {
auto sz = r.size();
char *str = new char[sz + 1];
string_range::traits_type::copy(str, r.data(), sz)[sz] = '\0';
std::char_traits<char>::copy(str, r.data(), sz)[sz] = '\0';
argp.vec.push_back(str);
}
/* terminate environment */